Add multi-line string literal parsing inside custom api code injection blocks

This commit is contained in:
Wojtek Figat
2024-11-19 16:17:11 +01:00
parent a7daf44330
commit 9bf680cc1a
2 changed files with 53 additions and 5 deletions

View File

@@ -35,6 +35,16 @@ API_STRUCT(NoDefault) struct TestDefaultValues
API_FIELD() float TestFloat10 = 1.f;
// Default value case 11
API_FIELD() float TestFloat11 = 1;
// Test code injection parsing
API_INJECT_CODE(csharp, ""
"namespace Test"
"{"
"\t/// <summary>\n\t/// Test code injection parsing\n\t/// </summary>"
" public static class TestClass"
" {"
" }"
"}")
};
// Test interface (name conflict with namespace)

View File

@@ -1526,16 +1526,54 @@ namespace Flax.Build.Bindings
return desc;
}
private static string ParseString(ref ParsingContext context)
{
// Read string (support multi-line string literals)
string str = string.Empty;
int startLine = -1;
while (true)
{
var token = context.Tokenizer.NextToken();
if (token.Type == TokenType.String)
{
if (startLine == -1)
startLine = context.Tokenizer.CurrentLine;
else if (startLine != context.Tokenizer.CurrentLine)
str += "\n";
var tokenStr = token.Value;
if (tokenStr.Length >= 2 && tokenStr[0] == '\"' && tokenStr[^1] == '\"')
tokenStr = tokenStr.Substring(1, tokenStr.Length - 2);
str += tokenStr;
}
else if (token.Type == TokenType.EndOfFile)
{
break;
}
else
{
if (str == string.Empty)
throw new Exception($"Expected {TokenType.String}, but got {token} at line {context.Tokenizer.CurrentLine}.");
context.Tokenizer.PreviousToken();
break;
}
}
// Apply automatic formatting for special characters
str = str.Replace("\\\"", "\"");
str = str.Replace("\\n", "\n");
str = str.Replace("\\\n", "\n");
str = str.Replace("\\\r\n", "\n");
str = str.Replace("\t", " ");
str = str.Replace("\\t", " ");
return str;
}
private static InjectCodeInfo ParseInjectCode(ref ParsingContext context)
{
context.Tokenizer.ExpectToken(TokenType.LeftParent);
var desc = new InjectCodeInfo();
context.Tokenizer.SkipUntil(TokenType.Comma, out desc.Lang);
desc.Code = context.Tokenizer.ExpectToken(TokenType.String).Value.Replace("\\\"", "\"");
desc.Code = desc.Code.Substring(1, desc.Code.Length - 2);
desc.Code = desc.Code.Replace("\\\n", "\n");
desc.Code = desc.Code.Replace("\\\r\n", "\n");
desc.Code = desc.Code.Replace("\t", " ");
desc.Code = ParseString(ref context);
context.Tokenizer.ExpectToken(TokenType.RightParent);
return desc;
}