public void CorrectParsingWithErrors(int line, int chr, string expectedContext) { var scriptErrors = @"Module M { Entity E { } error } "; var lineChr = new LineChr(line, chr); var rhe = rhetosDocumentFactory.CreateWithTestUri(scriptErrors, lineChr); var analysisResult = rhe.GetAnalysis(lineChr); Assert.IsTrue(analysisResult.SuccessfulRun); Assert.IsTrue(analysisResult.AllErrors.Any()); Console.WriteLine(string.Join("\n", analysisResult.AllErrors)); var contextDesc = string.Join(" / ", analysisResult.ConceptContext); Console.WriteLine($"Context at cursor ({line}, {chr}): {contextDesc}"); Assert.AreEqual(expectedContext, contextDesc); }
public void SignatureSameLineStatements(string script, int chr, int totalValidSignatures, string activeSignatureType, int?activeParameter) { var lineChr = new LineChr(0, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); if (totalValidSignatures == 0) { Console.WriteLine($"SignatureHelp: {signatureHelp}"); Assert.IsNull(signatureHelp.signatures); return; } Assert.IsNotNull(signatureHelp.signatures); Console.WriteLine($"Valid signatures: {signatureHelp.signatures.Count}"); Assert.AreEqual(totalValidSignatures, signatureHelp.signatures.Count); Console.WriteLine($"Active signature type: {signatureHelp.signatures[0].ConceptType.TypeName}"); Assert.AreEqual(activeSignatureType, signatureHelp.signatures[0].ConceptType.TypeName); if (activeParameter != null) // if activeParameter is null, activeSignature will also be { Assert.AreEqual(0, signatureHelp.activeSignature); } Console.WriteLine($"Active parameter: {signatureHelp.activeParameter}"); Assert.AreEqual(signatureHelp.activeParameter, activeParameter); }
// Due to unusual way the tokenizer works, if we capture errors during initial call to GetToken(), // valid tokens will be returned without error in subsequent calls private (Tokenizer tokenizer, List <CodeAnalysisError> capturedErrors) CreateTokenizerWithCapturedErrors() { var capturedErrors = new List <CodeAnalysisError>(); var safeTokenizer = new Tokenizer(textDocument, new FilesUtility(rhetosLogProvider)); try { safeTokenizer.GetTokens(); } catch (DslSyntaxException e) { var lineChr = new LineChr(e.FilePosition.BeginLine - 1, e.FilePosition.BeginColumn - 1); capturedErrors.Add(new CodeAnalysisError() { LineChr = lineChr, Message = e.Message }); } catch (Exception e) { capturedErrors.Add(new CodeAnalysisError() { Message = e.Message }); } return(safeTokenizer, capturedErrors); }
public string ShowPosition(LineChr lineChr) { var pos = GetPosition(lineChr); var lineText = ExtractLine(pos); return(ShowPositionOnLine(lineText, lineChr.Chr)); }
public void HoverDocumentation(int line, int chr, string expectedSubstring) { var script = @" Module module1 // comment { Entity SameLine { } Entity entity1 { Logging { } Reference name p. } Entity Entity2 { } error ' }"; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var hoverDocumentation = rhetosDocument.GetHoverDescriptionAtPosition(lineChr); Console.WriteLine($"Documentation:\n{hoverDocumentation.description}\n"); if (string.IsNullOrEmpty(expectedSubstring)) { Assert.IsNull(hoverDocumentation.description); return; } StringAssert.Contains(hoverDocumentation.description, expectedSubstring); }
public List <string> GetCompletionKeywordsAtPosition(LineChr lineChr) { var analysisResult = GetAnalysis(lineChr); if (analysisResult.IsInsideComment || analysisResult.IsAfterAnyErrorLine(lineChr)) { return(new List <string>()); } var typingToken = analysisResult.GetTokenBeingTypedAtCursor(lineChr); if (analysisResult.KeywordToken != null && analysisResult.KeywordToken != typingToken) { var fullAnalysis = GetAnalysis(); return(fullAnalysis.NonKeywordWords); } var lastParent = analysisResult.ConceptContext.LastOrDefault(); var validConcepts = lastParent == null ? rhetosAppContext.ConceptInfoTypes.ToList() : conceptQueries.ValidConceptsForParent(lastParent.GetType()); var keywords = validConcepts .Select(concept => ConceptInfoHelper.GetKeyword(concept)) .Where(keyword => keyword != null) .Distinct() .OrderBy(keyword => keyword) .ToList(); return(keywords); }
public Token GetTokenLeftOfPosition(LineChr lineChr) { if (lineChr.Chr > 0) { lineChr = new LineChr(lineChr.Line, lineChr.Chr - 1); } return(GetTokenAtPosition(lineChr)); }
private CodeAnalysisError CreateAnalysisError(DslSyntaxException e) { var lineChr = new LineChr(e.FilePosition.BeginLine - 1, e.FilePosition.BeginColumn - 1); return(new CodeAnalysisError() { LineChr = lineChr, Message = e.Message }); }
public Token GetTokenBeingTypedAtCursor(LineChr lineChr) { if (GetTokenAtPosition(lineChr) != null) { return(null); } return(GetTokenLeftOfPosition(lineChr)); }
public void CompletionEmptyFile() { var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(""); var lineChr = new LineChr(0, 3); var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr); Console.WriteLine($"Keywords: [{completion.Count}] {string.Join(",", completion)}"); Assert.AreEqual(172, completion.Count); }
public void CorrectKeywords(int line, int chr, string expectedKeyword) { var lineChr = new LineChr(line, chr); var rhe = rhetosDocumentFactory.CreateWithTestUri(complexScript, lineChr); var keywordToken = rhe.GetAnalysis(lineChr).KeywordToken; var keyword = keywordToken?.Value; Console.WriteLine($"Keyword at cursor ({line}, {chr}): {keyword}"); Assert.AreEqual(expectedKeyword, keyword); }
public void SignatureAtEof() { var lineChr = new LineChr(0, 20); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri("Entity module.entit", lineChr); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); Console.WriteLine($"Signature count: {signatureHelp.signatures?.Count}, active parameter: {signatureHelp.activeParameter}"); Assert.AreEqual(1, signatureHelp.signatures?.Count); Assert.AreEqual(2, signatureHelp.activeParameter); }
public void CompletionAtEof() { var lineChr = new LineChr(0, 3); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri("Ent", lineChr); var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr) .OrderBy(a => a) .ToList(); Console.WriteLine($"Keywords: [{completion.Count}] {string.Join(",", completion)}"); Assert.AreEqual(172, completion.Count); }
public Token GetTokenAtPosition(LineChr lineChr) { var position = TextDocument.GetPosition(lineChr); foreach (var token in Tokens) { if (token.Type != TokenType.EndOfFile && position >= token.PositionInDslScript && position < token.PositionEndInDslScript) { return(token); } } return(null); }
public void CorrectConceptContexts(int line, int chr, string expectedContext) { var lineChr = new LineChr(line, chr); var rhe = rhetosDocumentFactory.CreateWithTestUri(complexScript, lineChr); var analysis = rhe.GetAnalysis(lineChr); Console.WriteLine(analysis.TextDocument.ShowPosition(lineChr)); var context = analysis.ConceptContext; var contextDesc = string.Join(" / ", context); Console.WriteLine($"Context at cursor ({line}, {chr}): {contextDesc}"); Assert.AreEqual(expectedContext, contextDesc); }
public void QuotedSignatureHelp(int pos, bool expectedIsParam) { var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri("FilterBy a.b.c 'expression';"); var lineChr = new LineChr(0, pos); var positionText = rhetosDocument.TextDocument.ShowPosition(lineChr); Console.WriteLine($"\n{positionText}\n"); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); Console.WriteLine(signatureHelp.activeParameter); var isParam = signatureHelp.activeParameter == 2; Assert.AreEqual(expectedIsParam, isParam); }
public string GetTruncatedAtNextEndOfLine(LineChr lineChr) { if (Text.Length == 0) { return(""); } var pos = GetPosition(lineChr); while (pos < Text.Length) { if (Text[pos++] == '\n') { break; } } return(Text.Substring(0, pos)); }
public void ActiveSignature(int line, int chr, int totalValidSignatures, string activeSignatureType, int?activeParameter) { var script = @" Reference module1.entity1.name1 refm.refe; Module module1 { Entity entity1 { Reference name1 // comment } Entity entity2 { } }"; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); if (totalValidSignatures == 0) { Console.WriteLine($"SignatureHelp: {signatureHelp}"); Assert.IsNull(signatureHelp.signatures); return; } Assert.IsNotNull(signatureHelp.signatures); Console.WriteLine($"Valid signatures: {signatureHelp.signatures.Count}"); Assert.AreEqual(totalValidSignatures, signatureHelp.signatures.Count); Console.WriteLine($"Active signature types: {string.Join(",",signatureHelp.signatures.Select(a => a.ConceptType.TypeName))}"); var matchingSignature = signatureHelp.signatures.Single(a => a.ConceptType.TypeName == activeSignatureType); Assert.AreEqual(activeSignatureType, matchingSignature.ConceptType.TypeName); if (activeParameter != null) // if activeParameter is null, activeSignature will also be { Assert.AreEqual(0, signatureHelp.activeSignature); } Console.WriteLine($"Active parameter: {signatureHelp.activeParameter}"); Assert.AreEqual(signatureHelp.activeParameter, activeParameter); }
public void FullCompletionList(int line, int chr, int expectedCount, string expectedFullList) { var script = @" // comment Module module1 { Entity entity1 { Logging { } } Entity SameLine { } Ent Entit error ' }"; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); { var rhetosProjectContext = serviceProvider.GetRequiredService <RhetosProjectContext>(); var sqlDependsOn = rhetosProjectContext.DslSyntax.ConceptTypes.Where(a => a.Keyword == "SqlDependsOn"); Console.WriteLine(sqlDependsOn.Count()); Console.WriteLine(string.Join(",", sqlDependsOn.Select(a => a.TypeName))); } var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr); var fullList = string.Join(",", completion); Console.WriteLine($"Keywords: [{completion.Count}] {fullList}"); Console.WriteLine($"Expected: [{expectedCount}] {expectedFullList}"); Assert.AreEqual(expectedCount, completion.Count); Assert.AreEqual(expectedFullList, fullList); }
public void CompletionContext(int line, int chr, int validKeywordCount, string shouldContainKeyword, string shouldNotContainKeyword) { var script = @" // comment Module module1 { Entity entity1 { Logging { } } Entity SameLine { } Ent Entit error ' }"; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr); Console.WriteLine($"Keywords: [{completion.Count}] {string.Join(",", completion)}"); Assert.AreEqual(validKeywordCount, completion.Count); if (!string.IsNullOrEmpty(shouldContainKeyword)) { Console.WriteLine($"Should contain: {shouldContainKeyword}"); CollectionAssert.Contains(completion, shouldContainKeyword); } if (!string.IsNullOrEmpty(shouldNotContainKeyword)) { Console.WriteLine($"Should NOT contain: {shouldNotContainKeyword}"); CollectionAssert.DoesNotContain(completion, shouldNotContainKeyword); } }
public void SignatureAfterLastParameter() { var script = "Entity module.entity;\n"; { var lineChr = new LineChr(0, 20); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); Console.WriteLine($"Signature count: {signatureHelp.signatures?.Count}, active parameter: {signatureHelp.activeParameter}"); Assert.AreEqual(1, signatureHelp.signatures?.Count); Assert.AreEqual(2, signatureHelp.activeParameter); } { var lineChr = new LineChr(0, 21); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var signatureHelp = rhetosDocument.GetSignatureHelpAtPosition(lineChr); Assert.IsNull(signatureHelp.signatures); } }
private int GetActiveParameterForValidConcept(Type conceptType) { var activeParameter = 0; // we have parsed some members successfully for this concept type if (LastTokenParsed.ContainsKey(conceptType)) { activeParameter = ConceptInfoType.IndexOfParameter(conceptType, LastMemberReadAttempt[conceptType]); // if we have just typed a keyword OR have stopped typing a parameter (by pressing space, etc.), we need to advance to next parameter // keyword scenario is possible in nested concepts, where we already have valid parameters and are just typing a keyword var lineChr = new LineChr(Line, Chr); var atLastParsed = GetTokenAtPosition(lineChr) == LastTokenParsed[conceptType] || GetTokenLeftOfPosition(lineChr) == LastTokenParsed[conceptType]; var atKeyword = string.Equals(ConceptInfoHelper.GetKeyword(conceptType), LastTokenParsed[conceptType].Value, StringComparison.InvariantCultureIgnoreCase); if (atKeyword || !atLastParsed) { activeParameter++; } } return(activeParameter); }
public void CompletionNonKeywords(int line, int chr, string expectedNonKeywords) { var script = @" // comment Module module1 { Entity entity1 { Logging { } ShortString SameLine { AutoCode ; } } Ent ' Entit error }"; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr); var joined = string.Join(",", completion); Console.WriteLine($"NonKeywords: [{completion.Count}] {joined}"); if (expectedNonKeywords == null) { Console.WriteLine($"Not supported: returns non-keywords, but should return actual keywords. Problems with detecting ';' as statement termination symbol."); Assert.Inconclusive("Not supported feature / known bug."); } if (expectedNonKeywords.Contains("...")) { expectedNonKeywords = expectedNonKeywords.Replace(",...", ""); joined = new string(joined.Take(expectedNonKeywords.Length).ToArray()); } Assert.AreEqual(expectedNonKeywords, joined); }
public void CompletionForConceptParent(int line, int chr, bool shouldContainWithParent) { var script = @"Module ParentModule { WithParent Module1.Entity1 name1 param1; Entity Entity1 { } } WithParent Module2.Entity2 name2 ParentModule param2; "; var lineChr = new LineChr(line, chr); var rhetosDocument = rhetosDocumentFactory.CreateWithTestUri(script, lineChr); var completion = rhetosDocument.GetCompletionKeywordsAtPosition(lineChr); var valid = completion.Contains("WithParent"); Console.WriteLine($"Keyword 'WithParent' valid at pos: {valid}"); Assert.AreEqual(shouldContainWithParent, valid); }
public (List <RhetosSignature> signatures, int?activeSignature, int?activeParameter) GetSignatureHelpAtPosition(LineChr lineChr) { var analysis = GetAnalysis(lineChr); if (analysis.KeywordToken == null || analysis.IsAfterAnyErrorLine(lineChr)) { return(null, null, null); } var signaturesWithDocumentation = conceptQueries.GetSignaturesWithDocumentation(analysis.KeywordToken.Value); var validConcepts = analysis.GetValidConceptsWithActiveParameter(); if (!validConcepts.Any()) { return(signaturesWithDocumentation, null, null); } var sortedConcepts = validConcepts .Select(valid => ( valid.conceptType, valid.activeParamater, parameterCount: ConceptInfoType.GetParameters(valid.conceptType).Count, documentation: signaturesWithDocumentation.Single(sig => sig.ConceptInfoType == valid.conceptType) )) .OrderBy(valid => valid.activeParamater >= valid.parameterCount) .ThenBy(valid => valid.parameterCount) .ThenBy(valid => valid.conceptType.Name) .ToList(); var activeParameter = sortedConcepts.First().activeParamater; return(sortedConcepts.Select(sorted => sorted.documentation).ToList(), 0, activeParameter); }
public static Position ToPosition(this LineChr lineChr) { return(new Position(lineChr.Line, lineChr.Chr)); }
public int GetPosition(LineChr lineChr) { return(GetPosition(lineChr.Line, lineChr.Chr)); }
public bool IsAfterAnyErrorLine(LineChr lineChr) { return(AllErrors.Where(a => a.Severity == CodeAnalysisError.ErrorSeverity.Error).Any(error => lineChr.Line > error.LineChr.Line)); }
public bool IsAfterAnyErrorPosition(LineChr lineChr) { var pos = TextDocument.GetPosition(lineChr); return(AllErrors.Any(error => pos > TextDocument.GetPosition(error.LineChr))); }
public (string description, LineChr startPosition, LineChr endPosition) GetHoverDescriptionAtPosition(LineChr lineChr) { var analysis = GetAnalysis(lineChr); if (analysis.KeywordToken == null || analysis.IsAfterAnyErrorLine(lineChr)) { return(null, LineChr.Zero, LineChr.Zero); } var description = conceptQueries.GetFullDescription(analysis.KeywordToken.Value); if (string.IsNullOrEmpty(description)) { description = $"No documentation found for '{analysis.KeywordToken.Value}'."; } var startPosition = TextDocument.GetLineChr(analysis.KeywordToken.PositionInDslScript); var endPosition = lineChr; if (analysis.NextKeywordToken != null) { endPosition = TextDocument.GetLineChr(analysis.NextKeywordToken.PositionInDslScript - 1); } return(description, startPosition, endPosition); }