public override bool IsAvailableFor(IDeclaredElement declaredElement, ElementId?elementId) { if (!elementId.HasValue || declaredElement == null) { return(false); } if (!declaredElement.GetSolution().GetComponent <UnityYamlSupport>().IsUnityYamlParsingEnabled.Value) { return(false); } if (!declaredElement.GetSolution().GetComponent <AssetSerializationMode>().IsForceText) { return(false); } if (declaredElement is IMethod method) { var cache = method.GetSolution().GetComponent <UnitySceneDataLocalCache>(); return(cache.IsEventHandler(method)); } var unityApi = declaredElement.GetSolution().GetComponent <UnityApi>(); if (!unityApi.IsDescendantOfMonoBehaviour(declaredElement as ITypeElement)) { return(false); } return(true); }
public IEnumerable <AtomicRenameBase> CreateAtomicRenames(IDeclaredElement declaredElement, string newName, bool doNotAddBindingConflicts) { var settingsStore = declaredElement.GetSolution().GetComponent <ISettingsStore>(); var knownTypesCache = declaredElement.GetSolution().GetComponent <KnownTypesCache>(); return(new[] { new FormerlySerializedAsAtomicRename(declaredElement, newName, settingsStore, knownTypesCache) }); }
public static bool IsInterestingElement(IDeclaredElement element) { var solution = element.GetSolution(); var settings = solution.GetSettingsStore(); if (!settings.GetValue((UnitySettings key) => key.IsAssetIndexingEnabled)) { return(false); } var unityApi = element.GetSolution().TryGetComponent <UnityApi>(); if (unityApi == null) { return(false); } var assetSerializationMode = solution.GetComponent <AssetSerializationMode>(); var yamlParsingEnabled = solution.GetComponent <AssetIndexingSupport>().IsEnabled; var deferredController = solution.GetComponent <DeferredCacheController>(); if (!yamlParsingEnabled.Value || !assetSerializationMode.IsForceText || !deferredController.CompletedOnce.Value) { return(false); } switch (element) { case IClass c: return(unityApi.IsUnityType(c)); case IProperty _: case IMethod _: var eventsCount = solution .GetComponent <UnityEventsElementContainer>() .GetAssetUsagesCount(element, out var unityEventsEstimatedResult); var animationEventsCount = solution .GetComponent <AnimationEventUsagesContainer>() .GetEventUsagesCountFor(element, out var animationEventsEstimatedResult); var count = eventsCount + animationEventsCount; return(count > 0 || unityEventsEstimatedResult || animationEventsEstimatedResult); case IField field: return(unityApi.IsSerialisedField(field)); } return(false); }
// Used to filter files before searching for references. Files must contain ANY of these search terms. An // ISearchGuru implementation can narrow the search domain further (e.g. checking for files that contain ALL of // the terms). Method references require the element short name, while class references require the class's // file's asset guid public override IEnumerable <string> GetAllPossibleWordsInFile(IDeclaredElement element) { if (IsInterestingElement(element)) { var words = new List <string>(); // If it's a class, we only need the asset GUID if (element is IClass) { var metaFileGuidCache = element.GetSolution().GetComponent <MetaFileGuidCache>(); foreach (var sourceFile in element.GetSourceFiles()) { // If the element doesn't have the same name as the file it's in, Unity doesn't recognise it if (!sourceFile.Name.StartsWith(element.ShortName)) { continue; } var guid = metaFileGuidCache.GetAssetGuid(sourceFile); if (guid != null) { words.Add(guid); } } } else { words.Add(element.ShortName); } return(words); } return(EmptyList <string> .Instance); }
private void ProcessBehaviorContainer(IDeclaredElement element) { var solution = element.GetSolution(); var finder = solution.GetPsiServices().Finder; var searchDomain = _searchDomainFactory.CreateSearchDomain(solution, false); var consumer = new SearchResultsConsumer(); var progress = NullProgressIndicator.Create(); finder.Find(new[] { element }, searchDomain, consumer, SearchPattern.FIND_USAGES, progress); var contexts = consumer.GetOccurrences() .OfType <ReferenceOccurrence>() .Select(x => x.GetTypeElement().GetValidDeclaredElement()) .OfType <IClass>() .Where(x => x.IsContext()); foreach (var context in contexts) { var type = context.AsTypeInfo(); var declaration = context.GetDeclarations().FirstOrDefault(); if (declaration != null) { ProcessContext(type, declaration, false); foreach (var field in type.GetFields()) { ProcessField(declaration.GetProject(), field); } } } }
public ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { if (declaredElement is NitraDeclaredElement) return mySearchDomainFactory.CreateSearchDomain(declaredElement.GetSolution(), false); return EmptySearchDomain.Instance; }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; if (!element.IsFromUnityProject()) { return(false); } var solution = element.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); var cls = element as IClass; if (cls != null) { if (unityApi.IsUnityType(cls)) { flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } var method = element as IMethod; if (method != null) { EventFunctionMatch match; var function = unityApi.GetUnityEventFunction(method, out match); if (function != null && match == EventFunctionMatch.ExactMatch) { foreach (var parameter in function.Parameters) { if (parameter.IsOptional) { // Allows optional parameters to be marked as unused // TODO: Might need to process IParameter if optional gets more complex flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } flags = ImplicitUseKindFlags.Access; return(true); } } var field = element as IField; if (field != null && unityApi.IsUnityField(field)) { // Public fields gets exposed to the Unity Editor and assigned from the UI. // But it still should be checked if the field is ever accessed from the code. flags = ImplicitUseKindFlags.Assign; return(true); } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return(false); }
public ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { if (declaredElement is NitraDeclaredElement) { return(mySearchDomainFactory.CreateSearchDomain(declaredElement.GetSolution(), false)); } return(EmptySearchDomain.Instance); }
public bool IsApplicable(IDeclaredElement declaredElement) { if (!declaredElement.IsFromUnityProject()) { return(false); } var unityApi = declaredElement.GetSolution().GetComponent <UnityApi>(); return(unityApi.IsSerialisedField(declaredElement as IField)); }
private static bool IsInterestingElement(IDeclaredElement element) { var unityApi = element.GetSolution().TryGetComponent <UnityApi>(); if (unityApi == null) { return(false); } return(unityApi.IsUnityType(element as IClass) || unityApi.IsPotentialEventHandler(element as IMethod) || unityApi.IsPotentialEventHandler(element as IProperty)); }
public bool IsApplicable(IDeclaredElement declaredElement) { if (declaredElement is IMethod method) { var eventHandlerCache = declaredElement.GetSolution().GetComponent <UnityEventHandlerReferenceCache>(); return(eventHandlerCache.IsEventHandler(method)); } // TODO: Renaming properties return(false); }
public override ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { if (IsInterestingElement(declaredElement)) { var moduleFactory = declaredElement.GetSolution().TryGetComponent <UnityExternalFilesModuleFactory>(); if (moduleFactory != null) { return(mySearchDomainFactory.CreateSearchDomain(moduleFactory.PsiModule)); } } return(EmptySearchDomain.Instance); }
public ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { var uriIdentifier = declaredElement as IUriIdentifierDeclaredElement; if (uriIdentifier != null) { var cache = declaredElement.GetSolution().GetComponent <NTriplesCache>(); var files = cache.GetFilesContainingUri(uriIdentifier.GetNamespace(), uriIdentifier.GetLocalName()); return(this.mySearchDomainFactory.CreateSearchDomain(files)); } if (declaredElement is PrefixDeclaration) { var files = declaredElement.GetSourceFiles(); if (files.Count > 0) { return(this.mySearchDomainFactory.CreateSearchDomain(files[0])); } } return(this.mySearchDomainFactory.CreateSearchDomain(declaredElement.GetSolution(), false)); }
public ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { HybridCollection <IPsiSourceFile> files = declaredElement.GetSourceFiles(); if (!(declaredElement is RuleDeclaration)) { if (files.Count > 0) { return(mySearchDomainFactory.CreateSearchDomain(files[0])); } } return(mySearchDomainFactory.CreateSearchDomain(declaredElement.GetSolution(), false)); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { ISolution iSolution = element.GetSolution(); IList <IAssembly> allAssemblies = iSolution.GetAllAssemblies(); bool referencesUnity = allAssemblies.Any( assembly => assembly.Name == "UnityEngine" || assembly.Name == "UnityEditor"); if (!referencesUnity) { flags = ImplicitUseKindFlags.Default; return(false); } IClass cls = element as IClass; if (cls != null) { if (m_unitySolutionHelper.IsUnityImplicitType(cls, cls.Module)) { flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } IMethod method = element as IMethod; if (method != null && MonoBehaviourUtil.IsEventHandler(method.ShortName)) { ITypeElement containingType = method.GetContainingType(); if (containingType != null && m_unitySolutionHelper.IsUnityImplicitType(containingType, method.Module)) { flags = ImplicitUseKindFlags.Access; return(true); } } IField field = element as IField; if (field != null) { if (m_unitySolutionHelper.CheckFieldForUnityImplicits(field, field.Module)) { // Public fields gets exposed to the Unity Editor and assigned from the UI. But it still should be checked if the field is ever accessed from the code. flags = ImplicitUseKindFlags.Assign; return(true); } } flags = ImplicitUseKindFlags.Default; return(false); }
public int GetAssetUsagesCountInner(IDeclaredElement declaredElement, out bool estimatedResult) { myShellLocks.AssertReadAccessAllowed(); estimatedResult = false; if (!(declaredElement is IClrDeclaredElement clrDeclaredElement)) { return(0); } if (!IsPossibleEventHandler(declaredElement)) { return(0); } if (myExternalCount.GetCount(declaredElement.ShortName) > 0) { estimatedResult = true; } const int maxProcessCount = 5; if (myLocalUsages.GetOrEmpty(declaredElement.ShortName).Count > maxProcessCount) { estimatedResult = true; } var usageCount = 0; foreach (var(assetMethodData, c) in myLocalUsages.GetOrEmpty(declaredElement.ShortName).Take(maxProcessCount)) { var solution = declaredElement.GetSolution(); var module = clrDeclaredElement.Module; // we have already cache guid in merge method for methodData in myLocalUsages var guid = (assetMethodData.TargetScriptReference as ExternalReference)?.ExternalAssetGuid; if (guid == null) { continue; } var symbolTable = GetReferenceSymbolTable(solution, module, assetMethodData, guid); var resolveResult = symbolTable.GetResolveResult(assetMethodData.MethodName); if (resolveResult.ResolveErrorType == ResolveErrorType.OK && Equals(resolveResult.DeclaredElement, declaredElement)) { usageCount += c; } } return(usageCount); }
private IEnumerable <IDeclaredElement> GetRelatedTypesWithDerivedName(IDeclaredElement declaredElement) { var typeElement = declaredElement as ITypeElement; if (typeElement == null) { return(Enumerable.Empty <IDeclaredElement>()); } var solution = declaredElement.GetSolution().NotNull(); var linkedTypesService = solution.GetComponent <LinkedTypesService>(); var relatedTypes = linkedTypesService.GetLinkedTypes(typeElement); return(relatedTypes.Where(x => typeElement.ShortName.Contains(x.ShortName) || x.ShortName.Contains(typeElement.ShortName))); }
public Uri GetUrl(IDeclaredElement element) { if (!IsAvailable(element)) { return(null); } var unityApi = element.GetSolution().GetComponent <UnityApi>(); var keyword = element.GetUnityEventFunctionName(unityApi); keyword = ShowUnityHelp.FormatDocumentationKeyword(keyword); if (keyword == null) { return(null); } return(myShowUnityHelp.GetUri(keyword)); }
public override string GetEntityKind(IDeclaredElement declaredElement) { if (declaredElement.IsFromUnityProject()) { var unityApi = declaredElement.GetSolution().GetComponent <UnityApi>(); switch (declaredElement) { case IMethod method when unityApi.IsEventFunction(method): return("event function"); case IField field when unityApi.IsSerialisedField(field): return("serialised field"); } } return(base.GetEntityKind(declaredElement)); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; if (!element.IsFromUnityProject()) { return(false); } var solution = element.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); var cls = element as IClass; if (cls != null) { if (unityApi.IsUnityType(cls)) { flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } var method = element as IMethod; if (method != null && unityApi.IsUnityMessage(method)) { flags = ImplicitUseKindFlags.Access; return(true); } var field = element as IField; if (field != null && field.GetAccessRights() == AccessRights.PUBLIC) { var containingType = field.GetContainingType(); if (containingType != null && unityApi.IsUnityType(containingType)) { // Public fields gets exposed to the Unity Editor and assigned from the UI. But it still should be checked if the field is ever accessed from the code. flags = ImplicitUseKindFlags.Assign; return(true); } } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return(false); }
private static bool IsEventHandler(IDeclaredElement declaredElement) { var eventHandlerCache = declaredElement.GetSolution().GetComponent <UnityEventHandlerReferenceCache>(); switch (declaredElement) { case IMethod method: return(eventHandlerCache.IsEventHandler(method)); case IProperty property: var setter = property.Setter; return(setter != null && eventHandlerCache.IsEventHandler(setter)); default: return(false); } }
private static bool IsSerialisedField(IDeclaredElement declaredElement) { if (!(declaredElement is IField field)) { return(false); } if (!declaredElement.IsFromUnityProject()) { return(false); } var solution = declaredElement.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); return(unityApi.IsSerialisedField(field)); }
public override bool IsAvailableFor(IDeclaredElement declaredElement, ElementId?elementId) { if (!elementId.HasValue) { return(false); } if (declaredElement is IMethod method) { var cache = method.GetSolution().GetComponent <UnityEventHandlerReferenceCache>(); return(cache.IsEventHandler(method)); } var unityApi = declaredElement.GetSolution().GetComponent <UnityApi>(); if (!unityApi.IsDescendantOfMonoBehaviour(declaredElement as ITypeElement)) { return(false); } return(true); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; if (!element.IsFromUnityProject()) return false; var solution = element.GetSolution(); var unityApi = solution.GetComponent<UnityApi>(); var cls = element as IClass; if (cls != null) { if(unityApi.IsUnityType(cls)) { flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return true; } } var method = element as IMethod; if (method != null && unityApi.IsEventFunction(method)) { flags = ImplicitUseKindFlags.Access; return true; } var field = element as IField; if (field != null && unityApi.IsUnityField(field)) { // Public fields gets exposed to the Unity Editor and assigned from the UI. But it still should be checked if the field is ever accessed from the code. flags = ImplicitUseKindFlags.Assign; return true; } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return false; }
public static bool IsTestMethod(this IDeclaredElement declaredElement) { var unitTestElement = declaredElement.GetSolution().GetComponent <IUnitTestElementStuff>(); return((declaredElement is IMethod || declaredElement is IProperty) && unitTestElement.IsElementOfKind(declaredElement, UnitTestElementKind.Test)); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; if (!element.IsFromUnityProject()) { return(false); } var solution = element.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); switch (element) { case IClass cls when unityApi.IsUnityType(cls) || unityApi.IsComponentSystemType(cls) || IsUxmlFactory(cls): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case ITypeElement typeElement when unityApi.IsSerializableTypeDeclaration(typeElement): // TODO: We should only really mark it as in use if it's actually used somewhere // That is, it should be used as a field in a Unity type, or another serializable type flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case ITypeElement typeElement when IsImplicitlyUsedInterfaceType(typeElement): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case IMethod method: var function = unityApi.GetUnityEventFunction(method, out var match); if (function != null) { if (match == MethodSignatureMatch.ExactMatch) { flags = HasOptionalParameter(function) ? ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature : ImplicitUseKindFlags.Access; return(true); } return(false); } if (IsEventHandler(unityApi, method) || IsRequiredSignatureMethod(method) || IsAnimationEvent(solution, method) || IsImplicitlyUsedInterfaceMethod(method)) { flags = ImplicitUseKindFlags.Access; return(true); } break; case IField field when unityApi.IsSerialisedField(field): flags = ImplicitUseKindFlags.Assign; return(true); case IProperty property when IsEventHandler(unityApi, property.Setter) || IsImplicitlyUsedInterfaceProperty(property) || IsAnimationEvent(solution, property): flags = ImplicitUseKindFlags.Assign; return(true); } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return(false); }
public ISearchDomain GetDeclaredElementSearchDomain(IDeclaredElement declaredElement) { HybridCollection<IPsiSourceFile> files = declaredElement.GetSourceFiles(); if (!(declaredElement is RuleDeclaration)) { if (files.Count > 0) { return mySearchDomainFactory.CreateSearchDomain(files[0]); } } return mySearchDomainFactory.CreateSearchDomain(declaredElement.GetSolution(), false); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; try { if (!element.IsFromUnityProject()) { return(false); } } catch (Exception e) { /* * TODO: radically rethink Unity / non-Unity project detection. * Currently we check project's assemblies using extensions for IProject, * with no way to log errors and/or react to targetFrameworkChanges should they happen on the fly. * This should be replaced with something more stable and fast. */ myLogger.LogExceptionSilently(e); return(false); } var solution = element.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); switch (element) { case IClass cls when unityApi.IsUnityType(cls): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case IMethod method: var function = unityApi.GetUnityEventFunction(method, out var match); if (function != null && match == EventFunctionMatch.ExactMatch) { foreach (var parameter in function.Parameters) { if (parameter.IsOptional) { // Allows optional parameters to be marked as unused // TODO: Might need to process IParameter if optional gets more complex flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } flags = ImplicitUseKindFlags.Access; return(true); } break; case IField field when unityApi.IsUnityField(field): // Public fields gets exposed to the Unity Editor and assigned from the UI. // But it still should be checked if the field is ever accessed from the code. flags = ImplicitUseKindFlags.Assign; return(true); } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return(false); }
public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out ImplicitUseKindFlags flags) { flags = ImplicitUseKindFlags.Default; try { if (!element.IsFromUnityProject()) { return(false); } } catch (Exception e) { /* * TODO: radically rethink Unity / non-Unity project detection. * Currently we check project's assemblies using extensions for IProject, * with no way to log errors and/or react to targetFrameworkChanges should they happen on the fly. * This should be replaced with something more stable and fast. */ myLogger.LogExceptionSilently(e); return(false); } var solution = element.GetSolution(); var unityApi = solution.GetComponent <UnityApi>(); switch (element) { case IClass cls when unityApi.IsUnityType(cls) || unityApi.IsUnityECSType(cls): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case ITypeElement typeElement when IsImplicitlyUsedInterfaceType(typeElement): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case ITypeElement typeElement when unityApi.IsSerializableType(typeElement): // TODO: We should only really mark it as in use if it's actually used somewhere // That is, it should be used as a field in a Unity type, or another serializable type flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); case IMethod method when IsImplicitlyUsedInterfaceMethod(method): flags = ImplicitUseKindFlags.Access; return(true); case IMethod method: var function = unityApi.GetUnityEventFunction(method, out var match); if (function != null) { if (match == MethodSignatureMatch.ExactMatch) { foreach (var parameter in function.Parameters) { if (parameter.IsOptional) { // Allows optional parameters to be marked as unused // TODO: Might need to process IParameter if optional gets more complex flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return(true); } } flags = ImplicitUseKindFlags.Access; return(true); } return(false); } if (IsEventHandler(unityApi, method)) { flags = ImplicitUseKindFlags.Access; return(true); } if (IsSettingsProvider(method)) { flags = ImplicitUseKindFlags.Access; return(true); } break; case IField field when unityApi.IsSerialisedField(field) || unityApi.IsInjectedField(field): flags = ImplicitUseKindFlags.Assign; return(true); case IProperty property when IsEventHandler(unityApi, property.Setter) || IsImplicitlyUsedInterfaceProperty(property): flags = ImplicitUseKindFlags.Assign; return(true); } flags = ImplicitUseKindFlags.Default; // Value not used if we return false return(false); }
public IEnumerable <AtomicRenameBase> CreateAtomicRenames(IDeclaredElement declaredElement, string newName, bool doNotAddBindingConflicts) { return(new[] { new UnityEventTargetAtomicRename(declaredElement.GetSolution(), declaredElement, newName) }); }