Пример #1
0
        /// <summary>
        /// perform the required tasks based on the hover results
        /// </summary>
        /// <param name="hoverResult">result of the hover</param>
        private void ProcessHoverResult(HoverResult hoverResult)
        {
            switch (hoverResult)
            {
            case HoverResult.TravelerHovers:
                break;

            case HoverResult.TravelerSpeeds:
                _gameTraveler.HealthPoints -= 5;
                break;

            case HoverResult.TravelerCrashes:
                _gameTraveler.Lives--;
                break;

            case HoverResult.TravelerLands:
                break;

            case HoverResult.TravelerCruises:
                break;

            default:
                break;
            }
        }
Пример #2
0
        private HoverResult ProvideHover(Request request)
        {
            var matches = _ctx.Symbols
                          .Include(t => t.File)
                          .Where(t => t.Name.ToUpper() == request.PossibleWord.ToUpper());

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

            var count = matches.Count();

            if (count == 0)
            {
                return(null);
            }

            var result = new HoverResult();

            if (count > 1)
            {
                result.RequestId = request.Id;
                result.Main      = "Multiple defintions found.";
                return(result);
            }

            var match = matches.First();

            result.RequestId = request.Id;
            result.Main      = result.GetStyledMainSection(match.Name, match.Type);
            if (File.Exists(match.File.FilePath))
            {
                // TODO: Parse documentation if exists, for now return declaration line
                var lines      = File.ReadAllLines(match.File.FilePath);
                var decl       = lines[match.StartLine].Trim();
                var commentPos = decl.IndexOf("//");

                if (commentPos != -1)
                {
                    decl = decl.Remove(commentPos);
                }

                result.Contents = decl;
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// get HoverAction choice from the Traveler
        /// calculate the HoverResult based on the HoverActions and
        /// return it
        /// </summary>
        /// <returns>Hover Result</returns>
        private HoverResult Hover()
        {
            HoverResult hoverResult = HoverResult.None;
            HoverAction travelerHoverActionChoice;
            Random      random = new Random();

            travelerHoverActionChoice = _gameConsoleView.DisplayGetHoverActionChoice();

            if (travelerHoverActionChoice == HoverAction.Hover)
            {
                int travelhoverNumber = random.Next(1, 100);
                if (travelhoverNumber < _gameTraveler.HoverExperience)
                {
                    hoverResult = HoverResult.TravelerHovers;
                }
                else
                {
                    hoverResult = HoverResult.TravelerLands;
                }
            }
            else if (travelerHoverActionChoice == HoverAction.Cruise)
            {
                hoverResult = HoverResult.TravelerCruises;
            }
            else if (travelerHoverActionChoice == HoverAction.Speed)
            {
                int travelerHoverNumber = random.Next(1, 100);

                if (travelerHoverNumber > _gameTraveler.HoverExperience)
                {
                    hoverResult = HoverResult.TravelerSpeeds;
                }
                else
                {
                    hoverResult = HoverResult.TravelerCrashes;
                }
            }


            ProcessHoverResult(hoverResult);

            return(hoverResult);
        }
Пример #4
0
        /// <summary>
        /// display the results of the battle based on the BattleResult
        /// </summary>
        /// <param name="battleResult"></param>
        public void DisplayHoverResults(HoverResult hoverResult)
        {
            ConsoleUtil.HeaderText = "Hover Results";
            ConsoleUtil.DisplayReset();

            switch (hoverResult)
            {
            case HoverResult.TravelerHovers:
                ConsoleUtil.DisplayMessage("You can officially Hover! Hoverboards are awesome! Congratulations!");
                break;

            case HoverResult.TravelerSpeeds:
                ConsoleUtil.DisplayMessage("You are going way too fast and almost ran into a truck filled with Manure.");
                ConsoleUtil.DisplayMessage("You should gain some more experience.");
                break;

            case HoverResult.TravelerCrashes:
                ConsoleUtil.DisplayMessage("You were going too fast and crashed into a Manure truck.");
                ConsoleUtil.DisplayMessage("You should gain some more experience!");
                SoundPlayer player = new SoundPlayer();
                player.SoundLocation = AppDomain.CurrentDomain.BaseDirectory + "\\ihatemanure.wav";
                player.Play();
                break;

            case HoverResult.TravelerLands:
                ConsoleUtil.DisplayMessage("Frightened by inability to hover on the hoverboard, you land the hoverboard in fear!");
                break;

            case HoverResult.TravelerCruises:
                ConsoleUtil.DisplayMessage("You have mastered the hoverboard and start to cruise around. You notice the clock tower was struck by lightening. You notice a sweet vehicle cruising by and hover over to the bumper and cruise behind it.");
                break;

            default:
                break;
            }

            DisplayContinuePrompt();
        }
Пример #5
0
        /// <summary>
        /// Generates the LSIF content for a single document.
        /// </summary>
        /// <returns>The ID of the outputted Document vertex.</returns>
        /// <remarks>
        /// The high level algorithm here is we are going to walk across each token, produce a <see cref="Graph.Range"/> for that token's span,
        /// bind that token, and then link up the various features. So we'll link that range to the symbols it defines or references,
        /// will link it to results like Quick Info, and more. This method has a <paramref name="topLevelSymbolsResultSetTracker"/> that
        /// lets us link symbols across files, and will only talk about "top level" symbols that aren't things like locals that can't
        /// leak outside a file.
        /// </remarks>
        private static Id <Graph.LsifDocument> GenerateForDocument(
            SemanticModel semanticModel,
            HostLanguageServices languageServices,
            OptionSet options,
            IResultSetTracker topLevelSymbolsResultSetTracker,
            ILsifJsonWriter lsifJsonWriter,
            IdFactory idFactory)
        {
            var syntaxTree           = semanticModel.SyntaxTree;
            var sourceText           = semanticModel.SyntaxTree.GetText();
            var syntaxFactsService   = languageServices.GetRequiredService <ISyntaxFactsService>();
            var semanticFactsService = languageServices.GetRequiredService <ISemanticFactsService>();

            string?contentBase64Encoded = null;

            // TODO: move to checking the enum member mentioned in https://github.com/dotnet/roslyn/issues/49326 when that
            // is implemented. In the mean time, we'll use a heuristic of the path being a relative path as a way to indicate
            // this is a source generated file.
            if (!PathUtilities.IsAbsolute(syntaxTree.FilePath))
            {
                var text = semanticModel.SyntaxTree.GetText();

                // We always use UTF-8 encoding when writing out file contents, as that's expected by LSIF implementations.
                // TODO: when we move to .NET Core, is there a way to reduce allocatios here?
                contentBase64Encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(text.ToString()));
            }

            var documentVertex = new Graph.LsifDocument(new Uri(syntaxTree.FilePath, UriKind.RelativeOrAbsolute), GetLanguageKind(semanticModel.Language), contentBase64Encoded, idFactory);

            lsifJsonWriter.Write(documentVertex);
            lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId(), idFactory));

            // As we are processing this file, we are going to encounter symbols that have a shared resultSet with other documents like types
            // or methods. We're also going to encounter locals that never leave this document. We don't want those locals being held by
            // the topLevelSymbolsResultSetTracker, so we'll make another tracker for document local symbols, and then have a delegating
            // one that picks the correct one of the two.
            var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter, semanticModel.Compilation, idFactory);
            var symbolResultsTracker = new DelegatingResultSetTracker(symbol =>
            {
                if (symbol.Kind == SymbolKind.Local ||
                    symbol.Kind == SymbolKind.RangeVariable ||
                    symbol.Kind == SymbolKind.Label)
                {
                    // These symbols can go in the document local one because they can't escape methods
                    return(documentLocalSymbolsResultSetTracker);
                }
                else if (symbol.ContainingType != null && symbol.DeclaredAccessibility == Accessibility.Private && symbol.ContainingType.Locations.Length == 1)
                {
                    // This is a private member in a class that isn't partial, so it can't escape the file
                    return(documentLocalSymbolsResultSetTracker);
                }
                else
                {
                    return(topLevelSymbolsResultSetTracker);
                }
            });

            // We will walk the file token-by-token, making a range for each one and then attaching information for it
            var rangeVertices = new List <Id <Graph.Range> >();

            foreach (var syntaxToken in syntaxTree.GetRoot().DescendantTokens(descendIntoTrivia: true))
            {
                // We'll only create the Range vertex once it's needed, but any number of bits of code might create it first,
                // so we'll just make it Lazy.
                var lazyRangeVertex = new Lazy <Graph.Range>(() =>
                {
                    var rangeVertex = Graph.Range.FromTextSpan(syntaxToken.Span, sourceText, idFactory);

                    lsifJsonWriter.Write(rangeVertex);
                    rangeVertices.Add(rangeVertex.GetId());

                    return(rangeVertex);
                }, LazyThreadSafetyMode.None);

                var     declaredSymbol   = semanticFactsService.GetDeclaredSymbol(semanticModel, syntaxToken, CancellationToken.None);
                ISymbol?referencedSymbol = null;

                if (syntaxFactsService.IsBindableToken(syntaxToken))
                {
                    var bindableParent = syntaxFactsService.TryGetBindableParent(syntaxToken);

                    if (bindableParent != null)
                    {
                        var symbolInfo = semanticModel.GetSymbolInfo(bindableParent);
                        if (symbolInfo.Symbol != null && IncludeSymbolInReferences(symbolInfo.Symbol))
                        {
                            referencedSymbol = symbolInfo.Symbol;
                        }
                    }
                }

                if (declaredSymbol != null || referencedSymbol != null)
                {
                    // For now, we will link the range to the original definition, preferring the definition, as this is the symbol
                    // that would be used if we invoke a feature on this range. This is analogous to the logic in
                    // SymbolFinder.FindSymbolAtPositionAsync where if a token is both a reference and definition we'll prefer the
                    // definition. Once we start supporting hover we'll have to remove the "original definition" part of this, since
                    // since we show different contents for different constructed types there.
                    var symbolForLinkedResultSet   = (declaredSymbol ?? referencedSymbol) !.OriginalDefinition;
                    var symbolForLinkedResultSetId = symbolResultsTracker.GetResultSetIdForSymbol(symbolForLinkedResultSet);
                    lsifJsonWriter.Write(Edge.Create("next", lazyRangeVertex.Value.GetId(), symbolForLinkedResultSetId, idFactory));

                    if (declaredSymbol != null)
                    {
                        var definitionResultsId = symbolResultsTracker.GetResultIdForSymbol(declaredSymbol, Methods.TextDocumentDefinitionName, () => new DefinitionResult(idFactory));
                        lsifJsonWriter.Write(new Item(definitionResultsId.As <DefinitionResult, Vertex>(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), idFactory));
                    }

                    if (referencedSymbol != null)
                    {
                        // Create the link from the references back to this range. Note: this range can be reference to a
                        // symbol but the range can point a different symbol's resultSet. This can happen if the token is
                        // both a definition of a symbol (where we will point to the definition) but also a reference to some
                        // other symbol.
                        var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(referencedSymbol.OriginalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult(idFactory));
                        lsifJsonWriter.Write(new Item(referenceResultsId.As <ReferenceResult, Vertex>(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), idFactory, property: "references"));
                    }

                    // Write hover information for the symbol, if edge has not already been added.
                    // 'textDocument/hover' edge goes from the symbol ResultSet vertex to the hover result
                    // See https://github.com/Microsoft/language-server-protocol/blob/main/indexFormat/specification.md#resultset for an example.
                    if (symbolResultsTracker.ResultSetNeedsInformationalEdgeAdded(symbolForLinkedResultSet, Methods.TextDocumentHoverName))
                    {
                        // TODO: Can we avoid the WaitAndGetResult_CanCallOnBackground call by adding a sync method to compute hover?
                        var hover = HoverHandler.GetHoverAsync(semanticModel, syntaxToken.SpanStart, languageServices, CancellationToken.None).WaitAndGetResult_CanCallOnBackground(CancellationToken.None);
                        if (hover != null)
                        {
                            var hoverResult = new HoverResult(hover, idFactory);
                            lsifJsonWriter.Write(hoverResult);
                            lsifJsonWriter.Write(Edge.Create(Methods.TextDocumentHoverName, symbolForLinkedResultSetId, hoverResult.GetId(), idFactory));
                        }
                    }
                }
            }

            lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices, idFactory));

            // Write the folding ranges for the document.
            var foldingRanges      = FoldingRangesHandler.GetFoldingRanges(syntaxTree, languageServices, options, isMetadataAsSource: false, CancellationToken.None);
            var foldingRangeResult = new FoldingRangeResult(foldingRanges, idFactory);

            lsifJsonWriter.Write(foldingRangeResult);
            lsifJsonWriter.Write(Edge.Create(Methods.TextDocumentFoldingRangeName, documentVertex.GetId(), foldingRangeResult.GetId(), idFactory));

            lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId(), idFactory));
            return(documentVertex.GetId());
        }