private HashSet <IDeclaration> FindHotRootMethods([NotNull] ICSharpFile file, [NotNull] IPsiSourceFile sourceFile) { var api = file.GetSolution().GetComponent <UnityApi>(); var result = new HashSet <IDeclaration>(); var descendantsEnumerator = file.Descendants(); while (descendantsEnumerator.MoveNext()) { switch (descendantsEnumerator.Current) { case IClassLikeDeclaration classLikeDeclaration: var declaredSymbol = classLikeDeclaration.DeclaredElement; if (declaredSymbol == null || !declaredSymbol.GetAllSuperTypes().Any(t => t.GetClrName().Equals(KnownTypes.MonoBehaviour))) { descendantsEnumerator.SkipThisNode(); } break; case IMethodDeclaration methodDeclaration: // check that method is hot and add it to container var declaredElement = methodDeclaration.DeclaredElement; if (declaredElement == null) { break; } var name = declaredElement.ShortName; if (ourKnownHotMonoBehaviourMethods.Contains(name) && api.IsEventFunction(declaredElement)) { result.Add(methodDeclaration); } break; case IInvocationExpression invocationExpression: // we should find 'StartCoroutine' method, because passed symbol will be hot too var reference = (invocationExpression.InvokedExpression as IReferenceExpression)?.Reference; if (reference == null) { break; } var info = reference.Resolve(); if (info.ResolveErrorType != ResolveErrorType.OK) { break; } declaredElement = info.DeclaredElement as IMethod; if (declaredElement == null) { break; } var containingType = declaredElement.GetContainingType(); if (containingType == null || containingType.GetClrName().Equals(KnownTypes.MonoBehaviour) && declaredElement.ShortName.Equals("StartCoroutine")) { var arguments = invocationExpression.Arguments; if (arguments.Count == 0 || arguments.Count > 2) { break; } var firstArgument = arguments[0].Value; if (firstArgument == null) { break; } var coroutineMethodDeclaration = ExtractMethodDeclarationFromStartCoroutine(firstArgument); if (coroutineMethodDeclaration == null) { break; } var declarations = coroutineMethodDeclaration.GetDeclarationsIn(sourceFile).Where(t => t.GetSourceFile() == sourceFile); foreach (var declaration in declarations) { result.Add(declaration); } } break; } } return(result); }