-
Notifications
You must be signed in to change notification settings - Fork 216
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
增加对私有操作的支持 #351
增加对私有操作的支持 #351
Conversation
WalkthroughThe recent changes focus on enhancing the Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
未检测到合适的 ISSUE 推荐给您。感谢您的反馈!
|
@coderabbitai review |
Actions performedReview triggered.
|
UT Test - Ubuntu1 tests 1 ✅ 0s ⏱️ Results for commit 30737b9. |
UT Test - Windows1 tests 1 ✅ 0s ⏱️ Results for commit 30737b9. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Outside diff range and nitpick comments (2)
src/Natasha.CSharp/Natasha.CSharp.Compiler/Component/Syntax/NatashaCSharpSyntax.cs (1)
Line range hint
98-108
:
Consider adding error handling and logging, and fix the typographical error in the method name.The method lacks error handling and logging, and the method name contains a typographical error.
public static SyntaxTree FormatTree(CompilationUnitSyntax root, CSharpParseOptions? options, Encoding encoding, string filePath = "") { if (options == null) { options = _options; } try { return CSharpSyntaxTree.ParseText(root.NormalizeWhitespace().SyntaxTree.ToString(), options, filePath, encoding: encoding); } catch (Exception ex) { // Log the error Console.WriteLine($"Error formatting tree: {ex.Message}"); throw; } }src/Natasha.CSharp/Natasha.CSharp.Compiler/CompileUnit/AssemblyCSharpBuilder.Syntax.cs (1)
Line range hint
102-124
:
Consider adding error handling and logging.The method lacks error handling and logging.
private AssemblyCSharpBuilder InternalAddScript(string script, Encoding? encoding = null, string filePath = "") { if (_scriptHandle != null) { script = _scriptHandle(script); } try { var tree = NatashaCSharpSyntax.ParseTree(script, filePath, _options, encoding); var exception = NatashaExceptionAnalyzer.GetSyntaxException(tree); if (exception != null) { _exception = exception; throw exception; } else { lock (SyntaxTrees) { SyntaxTrees.Add(tree); } } return this; } catch (Exception ex) { // Log the error Console.WriteLine($"Error adding script: {ex.Message}"); throw; } }
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (5)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/CompileUnit/AssemblyCSharpBuilder.Syntax.cs (6 hunks)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Component/Syntax/NatashaCSharpSyntax.cs (3 hunks)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Extension/NatashaStringExtension.cs (1 hunks)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Utils/IgnoresAccessChecksToAttribute.cs (1 hunks)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Utils/NatashaPrivateAssemblySyntaxHelper.cs (1 hunks)
Files skipped from review due to trivial changes (1)
- src/Natasha.CSharp/Natasha.CSharp.Compiler/Utils/IgnoresAccessChecksToAttribute.cs
public static CompilationUnitSyntax ToAccessPrivateTree(this string script, params object[] objects) | ||
{ | ||
var tree = CSharpSyntaxTree.ParseText(script); | ||
var treeRoot = tree.GetCompilationUnitRoot(); | ||
var rootResult = NatashaPrivateAssemblySyntaxHelper.Handle(tree.GetCompilationUnitRoot(), objects); | ||
if (rootResult == null) | ||
{ | ||
return treeRoot; | ||
} | ||
return rootResult; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging, which could help in debugging and understanding failures.
public static CompilationUnitSyntax ToAccessPrivateTree(this string script, params object[] objects)
{
try
{
var tree = CSharpSyntaxTree.ParseText(script);
var treeRoot = tree.GetCompilationUnitRoot();
var rootResult = NatashaPrivateAssemblySyntaxHelper.Handle(tree.GetCompilationUnitRoot(), objects);
if (rootResult == null)
{
return treeRoot;
}
return rootResult;
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error processing script: {ex.Message}");
throw;
}
}
public static CompilationUnitSyntax? Handle(CompilationUnitSyntax rootSyntax, params object[] objects) | ||
{ | ||
if (objects == null || objects.Length == 0) | ||
{ | ||
return null; | ||
} | ||
HashSet<Type> types = new(objects.Select(obj => | ||
{ | ||
if (obj is Type type) | ||
{ | ||
return type; | ||
} | ||
else | ||
{ | ||
return obj.GetType(); | ||
} | ||
})!); | ||
return InternalHandle(rootSyntax, types); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling, logging, and thorough validation.
The method lacks error handling and logging, and the objects
parameter could be validated more thoroughly.
public static CompilationUnitSyntax? Handle(CompilationUnitSyntax rootSyntax, params object[] objects)
{
if (objects == null || objects.Length == 0)
{
return null;
}
try
{
HashSet<Type> types = new(objects.Select(obj =>
{
if (obj is Type type)
{
return type;
}
else if (obj != null)
{
return obj.GetType();
}
else
{
throw new ArgumentException("Object in the array is null.");
}
})!);
return InternalHandle(rootSyntax, types);
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error handling root syntax: {ex.Message}");
throw;
}
}
internal static CompilationUnitSyntax InternalHandle(CompilationUnitSyntax rootSyntax, HashSet<Type> types) | ||
{ | ||
HashSet<Assembly> assemblies = []; | ||
foreach (var type in types) | ||
{ | ||
var assembly = type.Assembly; | ||
if (!assemblies.Contains(assembly)) | ||
{ | ||
assemblies.Add(assembly); | ||
} | ||
} | ||
|
||
// 创建 assembly 级别的属性列表 | ||
var assemblyAttributeList = assemblies.Select(asm => | ||
{ | ||
var attrSyntax = SyntaxFactory.AttributeList( | ||
SyntaxFactory.SingletonSeparatedList( | ||
SyntaxFactory.Attribute( | ||
SyntaxFactory | ||
.IdentifierName("assembly:System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute")) | ||
.AddArgumentListArguments( | ||
SyntaxFactory.AttributeArgument( | ||
SyntaxFactory.ParseExpression($"\"{asm.GetName().Name!}\""))))); | ||
return attrSyntax | ||
.ReplaceToken( | ||
attrSyntax.CloseBracketToken, | ||
attrSyntax | ||
.CloseBracketToken | ||
.WithTrailingTrivia(SyntaxFactory.EndOfLine(Environment.NewLine))); | ||
}).ToArray(); | ||
|
||
|
||
// 将属性列表添加到 assembly 节点 | ||
rootSyntax = rootSyntax.AddAttributeLists(assemblyAttributeList); | ||
return rootSyntax; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling, logging, and optimizing the use of HashSet<Assembly>
.
The method lacks error handling and logging, and the use of HashSet<Assembly>
could be optimized.
internal static CompilationUnitSyntax InternalHandle(CompilationUnitSyntax rootSyntax, HashSet<Type> types)
{
try
{
HashSet<Assembly> assemblies = new();
foreach (var type in types)
{
var assembly = type.Assembly;
if (!assemblies.Contains(assembly))
{
assemblies.Add(assembly);
}
}
// 创建 assembly 级别的属性列表
var assemblyAttributeList = assemblies.Select(asm =>
{
var attrSyntax = SyntaxFactory.AttributeList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Attribute(
SyntaxFactory
.IdentifierName("assembly:System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute"))
.AddArgumentListArguments(
SyntaxFactory.AttributeArgument(
SyntaxFactory.ParseExpression($"\"{asm.GetName().Name!}\"")))));
return attrSyntax
.ReplaceToken(
attrSyntax.CloseBracketToken,
attrSyntax
.CloseBracketToken
.WithTrailingTrivia(SyntaxFactory.EndOfLine(Environment.NewLine)));
}).ToArray();
// 将属性列表添加到 assembly 节点
rootSyntax = rootSyntax.AddAttributeLists(assemblyAttributeList);
return rootSyntax;
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error processing root syntax: {ex.Message}");
throw;
}
}
public AssemblyCSharpBuilder Add(string script, Encoding? encoding = null, string filePath = "") | ||
{ | ||
return Add(script, _parsingBehavior, encoding); | ||
return Add(script, _parsingBehavior, encoding, filePath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging.
public AssemblyCSharpBuilder Add(string script, Encoding? encoding = null, string filePath = "")
{
try
{
return Add(script, _parsingBehavior, encoding, filePath);
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding script: {ex.Message}");
throw;
}
}
public AssemblyCSharpBuilder Add(CompilationUnitSyntax root, Encoding? encoding = null, string filePath = "") | ||
{ | ||
return Add(root, _parsingBehavior, encoding, filePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging.
public AssemblyCSharpBuilder Add(CompilationUnitSyntax root, Encoding? encoding = null, string filePath = "")
{
try
{
return Add(root, _parsingBehavior, encoding, filePath);
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding root syntax: {ex.Message}");
throw;
}
}
private AssemblyCSharpBuilder InternalAddRootSyntax(CompilationUnitSyntax root, Encoding? encoding = null, string filePath = "") | ||
{ | ||
var tree = NatashaCSharpSyntax.FormartTree(root, _options, encoding, filePath); | ||
var exception = NatashaExceptionAnalyzer.GetSyntaxException(tree); | ||
if (exception != null) | ||
{ | ||
throw exception; | ||
} | ||
else | ||
{ | ||
lock (SyntaxTrees) | ||
{ | ||
SyntaxTrees.Add(tree); | ||
} | ||
} | ||
return this; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging.
private AssemblyCSharpBuilder InternalAddRootSyntax(CompilationUnitSyntax root, Encoding? encoding = null, string filePath = "")
{
try
{
var tree = NatashaCSharpSyntax.FormartTree(root, _options, encoding, filePath);
var exception = NatashaExceptionAnalyzer.GetSyntaxException(tree);
if (exception != null)
{
throw exception;
}
else
{
lock (SyntaxTrees)
{
SyntaxTrees.Add(tree);
}
}
return this;
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding root syntax: {ex.Message}");
throw;
}
}
public AssemblyCSharpBuilder FastAddScriptWithoutCheck(string script, Encoding? encoding = null, string filePath = "") | ||
{ | ||
SyntaxTrees.Add(NatashaCSharpSyntax.ParseTree(script, filePath, _options, encoding)); | ||
return this; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging.
public AssemblyCSharpBuilder FastAddScriptWithoutCheck(string script, Encoding? encoding = null, string filePath = "")
{
try
{
SyntaxTrees.Add(NatashaCSharpSyntax.ParseTree(script, filePath, _options, encoding));
return this;
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding script without check: {ex.Message}");
throw;
}
}
public AssemblyCSharpBuilder FastAddSynataxWithoutCheck(CompilationUnitSyntax root, Encoding? encoding = null, string? filePath = null) | ||
{ | ||
SyntaxTrees.Add(NatashaCSharpSyntax.ParseTree(script, _options, encoding)); | ||
if (encoding != null || filePath != null) | ||
{ | ||
SyntaxTrees.Add(CSharpSyntaxTree.Create(root, _options, filePath?? root.SyntaxTree.FilePath, encoding ?? root.SyntaxTree.Encoding)); | ||
} | ||
else | ||
{ | ||
SyntaxTrees.Add(root.SyntaxTree); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging, and fix the typographical error in the method name.
The method lacks error handling and logging, and the method name contains a typographical error.
public AssemblyCSharpBuilder FastAddSyntaxWithoutCheck(CompilationUnitSyntax root, Encoding? encoding = null, string? filePath = null)
{
try
{
if (encoding != null || filePath != null)
{
SyntaxTrees.Add(CSharpSyntaxTree.Create(root, _options, filePath ?? root.SyntaxTree.FilePath, encoding ?? root.SyntaxTree.Encoding));
}
else
{
SyntaxTrees.Add(root.SyntaxTree);
}
return this;
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding syntax without check: {ex.Message}");
throw;
}
}
public AssemblyCSharpBuilder Add(string script, UsingLoadBehavior usingLoadBehavior, Encoding? encoding = null, string filePath = "") | ||
{ | ||
var usingScript = string.Empty; | ||
switch (usingLoadBehavior) | ||
{ | ||
case UsingLoadBehavior.WithDefault: | ||
return AddScript(NatashaLoadContext.DefaultContext.UsingRecorder + script, encoding); | ||
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString(); | ||
break; | ||
case UsingLoadBehavior.WithCurrent: | ||
if (Domain!.Name == NatashaLoadContext.DefaultName) | ||
{ | ||
return AddScript(NatashaLoadContext.DefaultContext.UsingRecorder + script, encoding); | ||
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString(); | ||
} | ||
return AddScript(LoadContext!.UsingRecorder + script, encoding); | ||
else | ||
{ | ||
usingScript = LoadContext!.UsingRecorder.ToString(); | ||
} | ||
break; | ||
case UsingLoadBehavior.WithAll: | ||
if (Domain!.Name == NatashaLoadContext.DefaultName) | ||
{ | ||
return AddScript(NatashaLoadContext.DefaultContext.UsingRecorder + script, encoding); | ||
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString(); | ||
} | ||
StringBuilder usingBuilder = new(); | ||
foreach (var item in LoadContext!.UsingRecorder._usings) | ||
else | ||
{ | ||
if (!NatashaLoadContext.DefaultContext.UsingRecorder.HasUsing(item)) | ||
StringBuilder usingBuilder = new(); | ||
foreach (var item in LoadContext!.UsingRecorder._usings) | ||
{ | ||
usingBuilder.AppendLine($"using {item};"); | ||
if (!NatashaLoadContext.DefaultContext.UsingRecorder.HasUsing(item)) | ||
{ | ||
usingBuilder.AppendLine($"using {item};"); | ||
} | ||
} | ||
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString() + usingBuilder; | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
return InternalAddScript(usingScript + script, encoding, filePath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling and logging.
The method lacks error handling and logging.
public AssemblyCSharpBuilder Add(string script, UsingLoadBehavior usingLoadBehavior, Encoding? encoding = null, string filePath = "")
{
try
{
var usingScript = string.Empty;
switch (usingLoadBehavior)
{
case UsingLoadBehavior.WithDefault:
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString();
break;
case UsingLoadBehavior.WithCurrent:
if (Domain!.Name == NatashaLoadContext.DefaultName)
{
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString();
}
else
{
usingScript = LoadContext!.UsingRecorder.ToString();
}
break;
case UsingLoadBehavior.WithAll:
if (Domain!.Name == NatashaLoadContext.DefaultName)
{
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString();
}
else
{
StringBuilder usingBuilder = new();
foreach (var item in LoadContext!.UsingRecorder._usings)
{
if (!NatashaLoadContext.DefaultContext.UsingRecorder.HasUsing(item))
{
usingBuilder.AppendLine($"using {item};");
}
}
usingScript = NatashaLoadContext.DefaultContext.UsingRecorder.ToString() + usingBuilder;
}
break;
default:
break;
}
return InternalAddScript(usingScript + script, encoding, filePath);
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"Error adding script with using load behavior: {ex.Message}");
throw;
}
}
Summary by CodeRabbit
New Features
ToAccessPrivateTree
extension method for parsing scripts intoCompilationUnitSyntax
.IgnoresAccessChecksToAttribute
to allow ignoring assembly access checks.NatashaPrivateAssemblySyntaxHelper
class for managing private assembly syntax with newHandle
method.Enhancements