예제 #1
0
        private IdentifierTooltipContent[] GetIdentifierContentsCore(
            DocumentRange documentRange, [NotNull] IContextBoundSettingsStore settings, [CanBeNull] IHighlighter highlighter)
        {
            DeclaredElementInfo info = FindDeclaredElement(documentRange);

            if (info == null)
            {
                return(EmptyArray <IdentifierTooltipContent> .Instance);
            }

            IdentifierTooltipContent standardContent = TryPresentColorized(info, settings)
                                                       ?? TryPresentNonColorized(highlighter, info.DeclaredElement, settings);

            bool replacesStandardContent;
            IdentifierTooltipContent additionalContent = TryGetAdditionalIdentifierContent(info, settings, out replacesStandardContent);

            if (replacesStandardContent)
            {
                standardContent   = additionalContent;
                additionalContent = null;
            }

            var results = new FrugalLocalList <IdentifierTooltipContent>();

            if (standardContent != null)
            {
                results.Add(standardContent);
            }
            if (additionalContent != null)
            {
                results.Add(additionalContent);
            }
            return(results.ToArray());
        }
        private FrugalLocalList <IAttribute> GetExistingFormerlySerializedAsAttributes(
            IFieldDeclaration fieldDeclaration, string nameArgument)
        {
            var list = new FrugalLocalList <IAttribute>();

            foreach (var attribute in fieldDeclaration.AttributesEnumerable)
            {
                var attributeTypeElement = attribute.TypeReference?.Resolve().DeclaredElement as ITypeElement;
                if (attributeTypeElement == null)
                {
                    continue;
                }

                if (Equals(attributeTypeElement.GetClrName(), KnownTypes.FormerlySerializedAsAttribute))
                {
                    var attributeInstance = attribute.GetAttributeInstance();
                    var nameParameter     = attributeInstance.PositionParameter(0);
                    if (nameParameter.IsConstant && nameParameter.ConstantValue.IsString() &&
                        (string)nameParameter.ConstantValue.Value == nameArgument)
                    {
                        list.Add(attribute);
                    }
                }
            }

            return(list);
        }
예제 #3
0
        private List <FileSystemPath> ExtractReferenceLocations([NotNull] IT4File file)
        {
            file.AssertContainsNoIncludeContext();
            var directives = file.GetThisAndIncludedFilesRecursive()
                             .SelectMany(it => it.Blocks)
                             .OfType <IT4AssemblyDirective>();
            var errors             = new FrugalLocalList <T4FailureRawData>();
            var directDependencies = directives.SelectNotNull(
                directive =>
            {
                var resolved = AssemblyReferenceResolver.Resolve(directive);
                if (resolved == null)
                {
                    errors.Add(CreateError(directive));
                }
                return(resolved);
            }
                ).AsList();

            if (!errors.IsEmpty)
            {
                throw new T4OutputGenerationException(errors);
            }
            AddBaseReferences(directDependencies, file);
            return(directDependencies);
        }
예제 #4
0
        public override IList <IAttributeInstance> GetAttributeInstances(IClrTypeName clrName)
        {
            if (AttributeClassNames.IsEmpty())
            {
                return(EmptyList <IAttributeInstance> .Instance);
            }

            if (!(GetDeclaration()?.GetFSharpSymbol() is FSharpEntity entity))
            {
                return(EmptyList <IAttributeInstance> .Instance);
            }

            var psiModule   = GetPsiModule();
            var entityAttrs = entity.Attributes;

            if (entityAttrs.Count == 0)
            {
                return(EmptyList <IAttributeInstance> .Instance);
            }

            var result = new FrugalLocalList <IAttributeInstance>();

            foreach (var fcsAttribute in entityAttrs)
            {
                if (new ClrTypeName(fcsAttribute.AttributeType.QualifiedBaseName).Equals(clrName))
                {
                    result.Add(new FSharpAttributeInstance(fcsAttribute, psiModule));
                }
            }

            return(result.ResultingList());
        }
예제 #5
0
    private IList<IDeclaration> GetPartialDeclarations([CanBeNull] IPsiSourceFile sourceFile)
    {
      var containingType = GetContainingType();
      if (containingType == null)
        return EmptyList<IDeclaration>.InstanceList;

      var declaration = GetDeclaration();
      if (declaration == null)
        return EmptyList<IDeclaration>.InstanceList;

      var list = new FrugalLocalList<IDeclaration>();
      var declarations =
        sourceFile != null
          ? containingType.GetDeclarationsIn(sourceFile)
          : containingType.GetDeclarations();

      foreach (var partDeclaration in declarations)
      {
        if (!(partDeclaration is IFSharpTypeElementDeclaration typeDeclaration))
          continue;

        foreach (var member in typeDeclaration.MemberDeclarations)
          if (member.DeclaredName == declaration.DeclaredName && Equals(this, member.DeclaredElement))
            list.Add(member);
      }

      return list.ResultingList();
    }
        public IEnumerable <T4AssemblyReferenceInfo> ExtractReferenceLocationsTransitive(IT4File file)
        {
            file.AssertContainsNoIncludeContext();
            var sourceFile  = file.PhysicalPsiSourceFile.NotNull();
            var projectFile = sourceFile.ToProjectFile().NotNull();
            var directives  = file.GetThisAndIncludedFilesRecursive()
                              .SelectMany(it => it.Blocks)
                              .OfType <IT4AssemblyDirective>();
            var errors             = new FrugalLocalList <T4FailureRawData>();
            var directDependencies = directives.SelectNotNull(
                directive =>
            {
                var resolved = AssemblyReferenceResolver.Resolve(directive);
                if (resolved == null)
                {
                    errors.Add(T4FailureRawData.FromElement(directive, "Unresolved assembly reference"));
                }

                return(resolved);
            }
                ).AsList();

            if (!errors.IsEmpty)
            {
                throw new T4OutputGenerationException(errors);
            }
            AddBaseReferences(directDependencies, file);
            return(LowLevelReferenceExtractionManager.ResolveTransitiveDependencies(
                       directDependencies,
                       projectFile.SelectResolveContext()
                       ));
        }
예제 #7
0
 private IncorrectMethodSignatureQuickFix(IMethodDeclaration methodDeclaration,
                                          MethodSignature expectedMethodSignature,
                                          MethodSignatureMatch match)
 {
     myMethodDeclaration        = methodDeclaration;
     myExpectedMethodSignatures = new FrugalLocalList <MethodSignature>();
     myExpectedMethodSignatures.Add(expectedMethodSignature);
     myMatches = new FrugalLocalList <MethodSignatureMatch>();
     myMatches.Add(match);
 }
예제 #8
0
 private IncorrectMethodSignatureQuickFix(IMethodDeclaration methodDeclaration,
                                          MethodSignature[] expectedMethodSignatures)
 {
     myMethodDeclaration        = methodDeclaration;
     myExpectedMethodSignatures = new FrugalLocalList <MethodSignature>(expectedMethodSignatures);
     myMatches = new FrugalLocalList <MethodSignatureMatch>();
     for (var i = 0; i < myExpectedMethodSignatures.Count; i++)
     {
         myMatches.Add(MethodSignatureMatch.NoMatch);
     }
 }
예제 #9
0
        public EventHandlerSymbolFilter(EventHandlerArgumentMode mode, string type, IPsiModule psiModule)
        {
            myTypes = new FrugalLocalList <IType>();

            myMode = mode;
            var predefinedTypes = psiModule.GetPredefinedType();

            switch (mode)
            {
            case EventHandlerArgumentMode.EventDefined:
                if (type != null)
                {
                    // Find the UnityEvent base type, and use the type parameters as the required arguments
                    // This only works for scenes serialised in Unity 2018.3 and below. The field was removed in 2018.4
                    var eventType             = TypeFactory.CreateTypeByCLRName(type, psiModule);
                    var unityEventType        = GetUnityEventType(eventType);
                    var unityEventTypeElement = unityEventType?.GetTypeElement();
                    if (unityEventType != null && unityEventTypeElement != null)
                    {
                        var(_, substitution) = unityEventType.Resolve();
                        var typeParameters = unityEventTypeElement.TypeParameters;
                        foreach (var t in typeParameters)
                        {
                            myTypes.Add(substitution.Apply(t));
                        }
                    }
                }
                break;

            case EventHandlerArgumentMode.UnityObject:
                myTypes.Add(type == null
                        ? TypeFactory.CreateTypeByCLRName(KnownTypes.Object, NullableAnnotation.Unknown, psiModule)
                        : TypeFactory.CreateTypeByCLRName(type, psiModule));
                break;

            case EventHandlerArgumentMode.Int:
                myTypes.Add(predefinedTypes.Int);
                break;

            case EventHandlerArgumentMode.Float:
                myTypes.Add(predefinedTypes.Float);
                break;

            case EventHandlerArgumentMode.String:
                myTypes.Add(predefinedTypes.String);
                break;

            case EventHandlerArgumentMode.Bool:
                myTypes.Add(predefinedTypes.Bool);
                break;
            }
        }
예제 #10
0
        protected FSharpFunctionBase([NotNull] ITypeMemberDeclaration declaration,
                                     [NotNull] FSharpMemberOrFunctionOrValue mfv, [CanBeNull] IFSharpTypeDeclaration typeDeclaration)
            : base(declaration, mfv)
        {
            var mfvTypeParams        = mfv.GenericParameters;
            var typeParams           = new FrugalLocalList <ITypeParameter>();
            var outerTypeParamsCount = typeDeclaration?.TypeParameters.Count ?? 0;

            for (var i = outerTypeParamsCount; i < mfvTypeParams.Count; i++)
            {
                typeParams.Add(new FSharpTypeParameterOfMethod(this, mfvTypeParams[i].DisplayName, i - outerTypeParamsCount));
            }
            TypeParameters = typeParams.ToList();

            ReturnType = mfv.IsConstructor || mfv.ReturnParameter.Type.IsUnit
        ? Module.GetPredefinedType().Void
        : FSharpTypesUtil.GetType(mfv.ReturnParameter.Type, declaration, TypeParameters, Module, true) ??
                         TypeFactory.CreateUnknownType(Module);

            var methodParams   = new FrugalLocalList <IParameter>();
            var mfvParamGroups = mfv.CurriedParameterGroups;

            if (mfvParamGroups.Count == 1 && mfvParamGroups[0].Count == 1 && mfvParamGroups[0][0].Type.IsUnit)
            {
                Parameters = EmptyList <IParameter> .InstanceList;
                return;
            }

            foreach (var paramsGroup in mfv.CurriedParameterGroups)
            {
                foreach (var param in paramsGroup)
                {
                    var paramType = param.Type;
                    var paramName = param.DisplayName;
                    methodParams.Add(new FSharpMethodParameter(param, this, methodParams.Count,
                                                               FSharpTypesUtil.GetParameterKind(param),
                                                               FSharpTypesUtil.GetType(paramType, declaration, TypeParameters, Module, false),
                                                               paramName.IsEmpty() ? SharedImplUtil.MISSING_DECLARATION_NAME : paramName));
                }
            }
            Parameters = methodParams.ToList();
        }
예제 #11
0
 public void AddFile(DirectoryEntryData directoryEntry)
 {
     if (directoryEntry.RelativePath.IsInterestingMeta())
     {
         MetaFiles.Add(directoryEntry);
     }
     else if (directoryEntry.RelativePath.IsInterestingAsset())
     {
         if (IsKnownBinaryAsset(directoryEntry))
         {
             KnownBinaryAssetFiles.Add(directoryEntry);
         }
         else if (IsAssetExcludedByName(directoryEntry.RelativePath))
         {
             ExcludedByNameAssetFiles.Add(directoryEntry);
         }
         else
         {
             AssetFiles.Add(directoryEntry);
         }
     }
 }
예제 #12
0
        private MethodSignature[] GetSignaturesFromRequiredSignatureAttribute(ITypeElement attributeTypeElement)
        {
            var signatures = new FrugalLocalList <MethodSignature>();

            foreach (var method in attributeTypeElement.Methods)
            {
                if (method.HasAttributeInstance(KnownTypes.RequiredSignatureAttribute, AttributesSource.Self))
                {
                    var parameterTypes = new FrugalLocalList <IType>();
                    var parameterNames = new FrugalLocalList <string>();
                    foreach (var parameter in method.Parameters)
                    {
                        parameterTypes.Add(parameter.Type);
                        parameterNames.Add(parameter.ShortName);
                    }

                    signatures.Add(new MethodSignature(method.ReturnType, method.IsStatic,
                                                       parameterTypes.AsIReadOnlyList(), parameterNames.AsIReadOnlyList()));
                }
            }

            return(signatures.IsEmpty ? null : signatures.ToArray());
        }
        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. Add inspections
                    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 == EventFunctionMatch.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);
                        }
                    }
                }
            }
        }
예제 #14
0
 public void AddDirectory(FileSystemPath directory)
 {
     Directories.Add(directory);
 }
예제 #15
0
        protected override void Analyze(IMemberOwnerDeclaration element, ElementProblemAnalyzerData data,
                                        IHighlightingConsumer consumer)
        {
            var typeElement = element.DeclaredElement;

            if (typeElement == null)
            {
                return;
            }

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

            var project = element.GetProject();

            if (project == null)
            {
                return;
            }

            var unityVersion = Api.GetNormalisedActualVersion(project);

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

            foreach (var instance in typeElement.GetAllClassMembers <IMethod>())
            {
                var unityEventFunction = Api.GetUnityEventFunction(instance.Member, unityVersion, out var match);
                if (unityEventFunction != null)
                {
                    map.AddValue(unityEventFunction, new Candidate(instance.Member, match));
                }
            }

            foreach (var(function, candidates) in map)
            {
                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;
                    PutEventToCustomData(method, data);
                    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)
                        {
                            hasExactMatch = true;
                            if (Equals(candidate.Method.GetContainingType(), typeElement))
                            {
                                PutEventToCustomData(candidate.Method, data);
                                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)
                        {
                            if (Equals(candidate.Method.GetContainingType(), typeElement))
                            {
                                var method = candidate.Method;
                                PutEventToCustomData(method, data);
                                AddMethodSignatureInspections(consumer, method, function, candidate.Match);
                            }
                        }
                    }
                }
            }
        }
		private IdentifierTooltipContent[] GetIdentifierContentsCore(
			DocumentRange documentRange, [NotNull] IContextBoundSettingsStore settings, [CanBeNull] IHighlighter highlighter) {

			DeclaredElementInfo info = FindDeclaredElement(documentRange);
			if (info == null)
				return EmptyArray<IdentifierTooltipContent>.Instance;

			IdentifierTooltipContent standardContent = TryPresentColorized(info, settings)
				?? TryPresentNonColorized(highlighter, info.DeclaredElement, settings);

			bool replacesStandardContent;
			IdentifierTooltipContent additionalContent = TryGetAdditionalIdentifierContent(info, settings, out replacesStandardContent);
			if (replacesStandardContent) {
				standardContent = additionalContent;
				additionalContent = null;
			}

			var results = new FrugalLocalList<IdentifierTooltipContent>();
			if (standardContent != null)
				results.Add(standardContent);
			if (additionalContent != null)
				results.Add(additionalContent);
			return results.ToArray();
		}