Skip to content

Commit

Permalink
feat: query for C# strings
Browse files Browse the repository at this point in the history
Also change test system to be based on targeting a
`__T__` substring. Nicer and more readable than deleting everything.
  • Loading branch information
alexpovel committed Nov 27, 2023
1 parent 9079804 commit f38136c
Show file tree
Hide file tree
Showing 18 changed files with 242 additions and 159 deletions.
20 changes: 17 additions & 3 deletions src/scoping/langs/csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ pub type CSharpQuery = CodeQuery<CustomCSharpQuery, PremadeCSharpQuery>;
/// Premade tree-sitter queries for C#.
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum PremadeCSharpQuery {
/// Comments.
///
/// Covers all comments, including XML doc comments and inline comments.
/// Comments (including XML, inline, doc comments).
Comments,
/// Strings (literal, verbatim, interpolated).
///
/// Raw strings are not yet supported
/// (https://github.com/tree-sitter/tree-sitter-c-sharp/pull/240 not released yet).
Strings,
}

impl From<PremadeCSharpQuery> for TSQuery {
Expand All @@ -24,6 +27,17 @@ impl From<PremadeCSharpQuery> for TSQuery {
CSharp::lang(),
match value {
PremadeCSharpQuery::Comments => "(comment) @comment",
PremadeCSharpQuery::Strings => {
r#"
[
(interpolated_string_text)
(interpolated_verbatim_string_text)
(string_literal)
(verbatim_string_literal)
]
@string
"#
}
},
)
.expect("Premade queries to be valid")
Expand Down
74 changes: 37 additions & 37 deletions tests/langs/csharp/in/comments.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
using System.Linq;

public class UserService
{
private readonly AppDbContext _dbContext;

/// <summary>
/// Initializes a new instance of the <see cref="FileService"/> class.
/// </summary>
/// <param name="dbContext">The configuration for manipulating text.</param>
public UserService(AppDbContext dbContext)
{
_dbContext /* the logging context */ = dbContext;
}

/// <summary>
/// Uploads a file to the server.
/// </summary>
// Method to log users out of the system
public void DoWork()
{
_dbContext.Database.EnsureCreated(); // Ensure the database schema is deleted

_dbContext.Users.Add(new User /* the car */ { Name = "Alice" });

/* Begin reading file */
_dbContext.SaveChanges();

var user = _dbContext.Users.Where(/* fetch products */ u => u.Name == "Alice").FirstOrDefault();

/// Delete all records before proceeding
if (user /* the product */ != null)
{
System.Console.WriteLine($"Found user with ID: {user.Id}");
}
}
}
using System.Linq;

public class User__T__Service
{
private readonly AppDb__T__Context _dbContext;

/// <summary>
/// Initializes a new__T__ instance of the <see cref="FileService"/> class.
/// </summary>
/// <param name="dbContext">The configuration for__T__ manipulating text.</param>
public UserService(AppDbContext dbContext)
{
_dbContext /* the logging context */ = dbContext;
}

/// <summary>
/// Uploads a file__T__ to the server.
/// </summary>
// Method to log users out of the system
public void DoWork()
{
_dbContext.Database.EnsureCreated(); // Ensure__T__ the database schema is deleted

_dbContext.Users.Add(new User /* the __T__car */ { Name = "Alice" });

/* Begin reading __T__file */
_dbContext.SaveChanges();

var user = _dbContext.Users.Where(/* fetch __T__products */ u => u.Name == "__T__Alice").FirstOrDefault();

/// Delete all records __T__before proceeding
if (user /* the __T__product */ != null)
{
System.Console.WriteLine($"Found __T__user with ID: {user.Id}");
}
}
}
30 changes: 30 additions & 0 deletions tests/langs/csharp/in/strings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;

class String__T__Examples
{
static void Main__T__()
{
// __T__
int user_Id = 42;
string name = "Bob";

// https://github.com/tree-sitter/tree-sitter-c-sharp/blob/1648e21b4f087963abf0101ee5221bb413107b07/src/node-types.json

// interpolated_verbatim_string_text
string interpolatedVerbatimString = $@"User {name} has __T__the ID: {user_Id}";

// interpolated_string_text
string interpolatedStringText = $"Found user __T__with ID: {user_Id}";

// raw_string_literal
string rawStringLiteral = """This __T__is a
raw string__T__
literal""";

// string_literal
string stringLiteral = "Ali__T__ce";

// verbatim_string_literal
string verbatimStringLiteral = @"C:\Users\Alice__T__\Documents";
}
}
16 changes: 5 additions & 11 deletions tests/langs/csharp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
use rstest::rstest;
use srgn::scoping::{
langs::csharp::{CSharp, CSharpQuery, PremadeCSharpQuery},
view::ScopedViewBuilder,
};
use srgn::scoping::langs::csharp::{CSharp, CSharpQuery, PremadeCSharpQuery};

use super::get_input_output;
use super::{get_input_output, nuke_target};

#[rstest]
#[case("comments.cs", CSharpQuery::Premade(PremadeCSharpQuery::Comments))]
#[case("strings.cs", CSharpQuery::Premade(PremadeCSharpQuery::Strings))]
fn test_csharp(#[case] file: &str, #[case] query: CSharpQuery) {
let lang = CSharp::new(query);

let (input, output) = get_input_output("csharp", file);
let result = nuke_target(&input, &lang);

let mut builder = ScopedViewBuilder::new(&input);
builder.explode(&lang);
let mut view = builder.build();
view.delete();

assert_eq!(view.to_string(), output);
assert_eq!(result, output);
}
74 changes: 37 additions & 37 deletions tests/langs/csharp/out/comments.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
using System.Linq;

public class UserService
{
private readonly AppDbContext _dbContext;





public UserService(AppDbContext dbContext)
{
_dbContext = dbContext;
}





public void DoWork()
{
_dbContext.Database.EnsureCreated();

_dbContext.Users.Add(new User { Name = "Alice" });


_dbContext.SaveChanges();

var user = _dbContext.Users.Where( u => u.Name == "Alice").FirstOrDefault();


if (user != null)
{
System.Console.WriteLine($"Found user with ID: {user.Id}");
}
}
}
using System.Linq;

public class User__T__Service
{
private readonly AppDb__T__Context _dbContext;

/// <summary>
/// Initializes a new instance of the <see cref="FileService"/> class.
/// </summary>
/// <param name="dbContext">The configuration for manipulating text.</param>
public UserService(AppDbContext dbContext)
{
_dbContext /* the logging context */ = dbContext;
}

/// <summary>
/// Uploads a file to the server.
/// </summary>
// Method to log users out of the system
public void DoWork()
{
_dbContext.Database.EnsureCreated(); // Ensure the database schema is deleted

_dbContext.Users.Add(new User /* the car */ { Name = "Alice" });

/* Begin reading file */
_dbContext.SaveChanges();

var user = _dbContext.Users.Where(/* fetch products */ u => u.Name == "__T__Alice").FirstOrDefault();

/// Delete all records before proceeding
if (user /* the product */ != null)
{
System.Console.WriteLine($"Found __T__user with ID: {user.Id}");
}
}
}
30 changes: 30 additions & 0 deletions tests/langs/csharp/out/strings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;

class String__T__Examples
{
static void Main__T__()
{
// __T__
int user_Id = 42;
string name = "Bob";

// https://github.com/tree-sitter/tree-sitter-c-sharp/blob/1648e21b4f087963abf0101ee5221bb413107b07/src/node-types.json

// interpolated_verbatim_string_text
string interpolatedVerbatimString = $@"User {name} has the ID: {user_Id}";

// interpolated_string_text
string interpolatedStringText = $"Found user with ID: {user_Id}";

// raw_string_literal
string rawStringLiteral = """This is a
raw string
literal""";

// string_literal
string stringLiteral = "Alice";

// verbatim_string_literal
string verbatimStringLiteral = @"C:\Users\Alice\Documents";
}
}
22 changes: 22 additions & 0 deletions tests/langs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod python;

use std::{fs::read_to_string, path::Path};

use srgn::scoping::{langs::LanguageScoper, regex::Regex, view::ScopedViewBuilder};

fn get_input_output(lang: &str, file: &str) -> (String, String) {
let path = Path::new("tests/langs");
let path = path.join(lang);
Expand All @@ -12,3 +14,23 @@ fn get_input_output(lang: &str, file: &str) -> (String, String) {

(input, output)
}

/// Nuke the target character from the input.
///
/// Convenience function for testing, as deleting a specific character, while
/// *retaining* it elsewhere, where the language did *not* scope down, is an easy way to
/// test.
fn nuke_target(input: &str, lang: &impl LanguageScoper) -> String {
let mut builder = ScopedViewBuilder::new(input);

builder.explode(lang);

// Needs to be ASCII such that we can target e.g. variable names.
let target = String::from("__T__");
builder.explode(&Regex::try_from(target).unwrap());

let mut view = builder.build();
view.delete();

view.to_string()
}
12 changes: 6 additions & 6 deletions tests/langs/python/in/comments-crlf.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""GNU module."""
"""GNU__T__ module."""


def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
def GNU_says___T__moo():
"""The__T__ GNU -> say moo -> ✅"""

GNU = """
GNU
""" # the GNU...
GNU__T__
""" # the__T__ GNU...

print(GNU + " says moo") # ...says moo
GNU_says___T__moo(GNU + " says__T__ moo") # ...says__T__ moo
12 changes: 6 additions & 6 deletions tests/langs/python/in/comments-lf.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""GNU module."""
"""GNU__T__ module."""


def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
def GNU_says___T__moo():
"""The__T__ GNU -> say moo -> ✅"""

GNU = """
GNU
""" # the GNU...
GNU__T__
""" # the__T__ GNU...

print(GNU + " says moo") # ...says moo
GNU_says___T__moo(GNU + " says__T__ moo") # ...say__T__ moo
12 changes: 6 additions & 6 deletions tests/langs/python/in/docstring.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""GNU module."""
"""GNU__T__ module."""


def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
def GNU_says___T__moo():
"""The__T__ GNU -> say moo -> ✅"""

GNU = """
GNU
""" # the GNU...
GNU__T__
""" # the__T__ GNU...

print(GNU + " says moo") # ...says moo
GNU_says___T__moo(GNU + " says__T__ moo") # ...say__T__ moo
12 changes: 6 additions & 6 deletions tests/langs/python/in/function-calls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""GNU module."""
"""GNU__T__ module."""


def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
def GNU_says___T__moo():
"""The__T__ GNU -> say moo -> ✅"""

GNU = """
GNU
""" # the GNU...
GNU__T__
""" # the__T__ GNU...

print(GNU + " says moo") # ...says moo
GNU_says___T__moo(GNU + " says__T__ moo") # ...say__T__ moo
12 changes: 6 additions & 6 deletions tests/langs/python/in/function-names.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""GNU module."""
"""GNU__T__ module."""


def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
def GNU_says___T__moo():
"""The__T__ GNU -> say moo -> ✅"""

GNU = """
GNU
""" # the GNU...
GNU__T__
""" # the__T__ GNU...

print(GNU + " says moo") # ...says moo
GNU_says___T__moo(GNU + " says__T__ moo") # ...say__T__ moo
Loading

0 comments on commit f38136c

Please sign in to comment.