Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring provider to convert regular string to interpolated string #48502

Merged
merged 17 commits into from Oct 17, 2020

Conversation

louis-z
Copy link
Contributor

@louis-z louis-z commented Oct 11, 2020

Fixes #48219

The refactoring is offered for regular string literals that

  • contain either '{' or '}', and
  • are not assigned to a constant

@louis-z louis-z requested a review from a team as a code owner October 11, 2020 21:19
Comment on lines 27 to 29
=> isVerbatim
? text.Substring("@'".Length, text.Length - "@''".Length)
: text.Substring("'".Length, text.Length - "''".Length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is less repetitive, and IMO still readable.

Suggested change
=> isVerbatim
? text.Substring("@'".Length, text.Length - "@''".Length)
: text.Substring("'".Length, text.Length - "''".Length);
=> text[(isVerbatim ? "@'" : "'").Length..];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the same result, you're missing ^1 on the end.

Personally I find it confusing that this uses the string length of a literal to work out how many characters to remove, particularly as the literals don't have the right quotation marks in them, nor would the text in question have double quotes. I also don't see why this can't be in the language agnostic layer, since isVerbatim will always be false for VB anyway. I would simply write this as:

private static string GetTextWithoutQuotes(string text, bool isVerbatim)
{
    // Trim off an extra character for the @ symbol for verbatim strings
	var startIndex = isVerbatim ? 2 : 1;
	return text[startIndex..^1];
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, please onl yhave this refactoring if there are no diagnotics on the expr. and probably a good time to ensure that the string is terminated. and pleas have test for thie case "foo{ (i.e. an unterminated literal).

Copy link
Contributor Author

@louis-z louis-z Oct 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the same result, you're missing ^1 on the end.

Personally I find it confusing that this uses the string length of a literal to work out how many characters to remove, particularly as the literals don't have the right quotation marks in them, nor would the text in question have double quotes. I also don't see why this can't be in the language agnostic layer, since isVerbatim will always be false for VB anyway. I would simply write this as:

private static string GetTextWithoutQuotes(string text, bool isVerbatim)
{
    // Trim off an extra character for the @ symbol for verbatim strings
	var startIndex = isVerbatim ? 2 : 1;
	return text[startIndex..^1];
}

I agree, this is a better way of doing things.

(The code I used was copied from https://github.com/dotnet/roslyn/blob/master/src/Features/CSharp/Portable/ConvertToInterpolatedString/CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs#L25)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to extract all of this into a helper utilities class they can both call into.

Copy link
Member

@Youssef1313 Youssef1313 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does something like the following work?

public class C
{
    public void M(string code = @"class Program{}")
    {
    }
}

If it works, add a test for it.
If it doesn't work, then this is an edge case that IMO can be addressed later, but it's up to the team whether they want it in this PR or to be addressed later. (I think it may not be hard to add it if it doesn't currently work)

Just noticed how crap I just wrote 😄
This may be something to check with const interpolated strings if it came with C# 10.

Comment on lines 27 to 29
=> isVerbatim
? text.Substring("@'".Length, text.Length - "@''".Length)
: text.Substring("'".Length, text.Length - "''".Length);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the same result, you're missing ^1 on the end.

Personally I find it confusing that this uses the string length of a literal to work out how many characters to remove, particularly as the literals don't have the right quotation marks in them, nor would the text in question have double quotes. I also don't see why this can't be in the language agnostic layer, since isVerbatim will always be false for VB anyway. I would simply write this as:

private static string GetTextWithoutQuotes(string text, bool isVerbatim)
{
    // Trim off an extra character for the @ symbol for verbatim strings
	var startIndex = isVerbatim ? 2 : 1;
	return text[startIndex..^1];
}

@CyrusNajmabadi
Copy link
Member

Could you show a picture of the refactoring and lightbulb?

Comment on lines 65 to 68
var startToken = generator.CreateInterpolatedStringStartToken(isVerbatimStringLiteral)
.WithLeadingTrivia(literalExpression.GetLeadingTrivia());
var endToken = generator.CreateInterpolatedStringEndToken()
.WithTrailingTrivia(literalExpression.GetTrailingTrivia());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var startToken = generator.CreateInterpolatedStringStartToken(isVerbatimStringLiteral)
.WithLeadingTrivia(literalExpression.GetLeadingTrivia());
var endToken = generator.CreateInterpolatedStringEndToken()
.WithTrailingTrivia(literalExpression.GetTrailingTrivia());
var startToken = generator.CreateInterpolatedStringStartToken(isVerbatimStringLiteral).WithLeadingTrivia(literalExpression.GetLeadingTrivia());
var endToken = generator.CreateInterpolatedStringEndToken().WithTrailingTrivia(literalExpression.GetTrailingTrivia());

@CyrusNajmabadi
Copy link
Member

Very close IMO. Only need some minor changes.

@jinujoseph jinujoseph added Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee. Feature Request labels Oct 12, 2020
@jinujoseph jinujoseph added this to InQueue in IDE: CommunityPR via automation Oct 12, 2020
@jinujoseph jinujoseph moved this from InQueue to BuddyAssigned in IDE: CommunityPR Oct 12, 2020
@louis-z
Copy link
Contributor Author

louis-z commented Oct 14, 2020

@CyrusNajmabadi, there are still a few unresolved conversations... Personally I feel they are not showstoppers, but LMK if you feel otherwise and I will attempt to address them.

And thanks again for all your input.

…RegularStringToInterpolatedStringRefactoringProvider.cs
…RegularStringToInterpolatedStringRefactoringProvider.cs
…RegularStringToInterpolatedStringRefactoringProvider.cs
…RegularStringToInterpolatedStringRefactoringProvider.cs
…RegularStringToInterpolatedStringRefactoringProvider.cs
…RegularStringToInterpolatedStringRefactoringProvider.cs
IDE: CommunityPR automation moved this from BuddyAssigned to LGTM Oct 14, 2020
@louis-z
Copy link
Contributor Author

louis-z commented Oct 16, 2020

Hey @CyrusNajmabadi, I noticed some checks had failed. Do I need to do anything else on my end to get the PR merged? Do you need me to rebase?

@CyrusNajmabadi
Copy link
Member

rerunning test now. LMK when you're green :)

@louis-z
Copy link
Contributor Author

louis-z commented Oct 17, 2020

Still not green. :(

@louis-z
Copy link
Contributor Author

louis-z commented Oct 17, 2020

Ok @CyrusNajmabadi, we're good to go. 😉

@CyrusNajmabadi
Copy link
Member

Awesome!

@CyrusNajmabadi CyrusNajmabadi merged commit 81b6a51 into dotnet:master Oct 17, 2020
IDE: CommunityPR automation moved this from LGTM to Completed Oct 17, 2020
@ghost ghost added this to the Next milestone Oct 17, 2020
@CyrusNajmabadi
Copy link
Member

thanks!

@louis-z louis-z deleted the issue-48219 branch October 17, 2020 17:33
@jinujoseph jinujoseph moved this from Completed-Sprint178 to Completed in IDE: CommunityPR Oct 18, 2020
@allisonchou allisonchou modified the milestones: Next, 16.9.P2 Nov 24, 2020
@jinujoseph jinujoseph moved this from Completed-Sprint179 to Completed 2020 in IDE: CommunityPR Apr 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee. Feature Request
Projects
IDE: CommunityPR
  
Completed 2020
Development

Successfully merging this pull request may close these issues.

Feature request: Convert to interpolated string code refactoring
6 participants