Skip to content

Commit 21d8e8f

Browse files
committed
fix #518
1 parent 3229340 commit 21d8e8f

File tree

5 files changed

+169
-155
lines changed

5 files changed

+169
-155
lines changed

CSharp.lua/LuaSyntaxGenerator.cs

Lines changed: 147 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ limitations under the License.
3030
using Microsoft.CodeAnalysis.Emit;
3131

3232
using CSharpLua.LuaAst;
33+
using System.Text.RegularExpressions;
3334

3435
namespace CSharpLua {
3536
internal sealed class PartialTypeDeclaration : IComparable<PartialTypeDeclaration> {
@@ -202,7 +203,7 @@ public LuaSyntaxGenerator(IEnumerable<(string Text, string Path)> codes, IEnumer
202203
public LuaSyntaxGenerator(IEnumerable<(string Text, string Path)> codes, IEnumerable<Stream> libs, IEnumerable<string> cscArguments, IEnumerable<Stream> metas, SettingInfo setting) {
203204
Setting = setting;
204205
(compilation_, CommandLineArguments) = BuildCompilation(codes, libs, cscArguments);
205-
XmlMetaProvider = new XmlMetaProvider(metas);
206+
XmlMetaProvider = new XmlMetaProvider(this, metas);
206207
if (Setting.ExportEnums != null) {
207208
exportEnums_.UnionWith(Setting.ExportEnums);
208209
}
@@ -1649,7 +1650,7 @@ private bool IsPropertyFieldInternal(IPropertySymbol symbol) {
16491650
return false;
16501651
}
16511652

1652-
return symbol.IsAutoProperty();
1653+
return IsAutoProperty(symbol);
16531654
}
16541655

16551656
internal bool IsPropertyTemplate(IPropertySymbol symbol) {
@@ -1658,8 +1659,8 @@ internal bool IsPropertyTemplate(IPropertySymbol symbol) {
16581659
if (node == null) {
16591660
return false;
16601661
} else {
1661-
return node.HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Get)
1662-
|| symbol.GetDeclaringSyntaxNode().HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Set);
1662+
return HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Get)
1663+
|| HasCSharpLuaAttribute(symbol.GetDeclaringSyntaxNode(), LuaDocumentStatement.AttributeFlags.Set);
16631664
}
16641665
});
16651666
}
@@ -2144,5 +2145,147 @@ internal LuaIdentifierNameSyntax GetTypeShortName(ISymbol symbol, LuaSyntaxNodeT
21442145
}
21452146

21462147
#endregion
2148+
2149+
2150+
#region HasCSharpLuaAttribute
2151+
2152+
private readonly ConcurrentDictionary<SyntaxNode, string> syntaxNodeDocumentTrivia_ = new ();
2153+
2154+
public bool HasMetadataAttribute(ISymbol symbol) {
2155+
var node = symbol.GetDeclaringSyntaxNode();
2156+
if (node != null) {
2157+
return HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Metadata);
2158+
}
2159+
return false;
2160+
}
2161+
2162+
public bool HasParamsAttribute(ISymbol symbol) {
2163+
var node = symbol.GetDeclaringSyntaxNode();
2164+
if (node != null) {
2165+
return HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Params);
2166+
}
2167+
return false;
2168+
}
2169+
2170+
public bool HasCSharpLuaAttribute(SyntaxNode node, LuaDocumentStatement.AttributeFlags attribute) {
2171+
return HasCSharpLuaAttribute(node, attribute, out _);
2172+
}
2173+
2174+
private string GetSyntaxNodeDocumentTriviaStr(SyntaxNode node) {
2175+
return syntaxNodeDocumentTrivia_.GetOrAdd(node, node => {
2176+
var documentTrivia = node.GetLeadingTrivia().FirstOrDefault(i => i.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia));
2177+
return documentTrivia != default ? documentTrivia.ToString() : null;
2178+
});
2179+
}
2180+
2181+
public bool HasCSharpLuaAttribute(SyntaxNode node, LuaDocumentStatement.AttributeFlags attribute, out string text) {
2182+
text = null;
2183+
string document = GetSyntaxNodeDocumentTriviaStr(node);
2184+
if (document != null && document.Contains(LuaDocumentStatement.ToString(attribute))) {
2185+
text = document;
2186+
return true;
2187+
}
2188+
return false;
2189+
}
2190+
2191+
public string GetCodeTemplateFromAttribute(ISymbol symbol) {
2192+
var node = symbol.GetDeclaringSyntaxNode();
2193+
if (node != null) {
2194+
if (symbol.Kind == SymbolKind.Field) {
2195+
node = node.Parent.Parent;
2196+
}
2197+
if (HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Template, out string text)) {
2198+
return GetCodeTemplateFromAttributeText(text, codeTemplateAttributeRegex_);
2199+
}
2200+
} else {
2201+
string xml = symbol.GetDocumentationCommentXml();
2202+
if (xml != null) {
2203+
return GetCodeTemplateFromAttributeText(xml, codeTemplateAttributeRegex_);
2204+
}
2205+
}
2206+
return null;
2207+
}
2208+
2209+
public (string get, string set) GetPropertyTemplateFromAttribute(ISymbol symbol) {
2210+
var node = symbol.GetDeclaringSyntaxNode();
2211+
string get = null;
2212+
string set = null;
2213+
if (node != null) {
2214+
if (symbol.Kind == SymbolKind.Field) {
2215+
node = node.Parent.Parent;
2216+
}
2217+
if (HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Get, out string getText)) {
2218+
get = GetCodeTemplateFromAttributeText(getText, codeGetAttributeRegex_);
2219+
}
2220+
if (HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Set, out string setText)) {
2221+
set = GetCodeTemplateFromAttributeText(setText, codeSetAttributeRegex_);
2222+
}
2223+
}
2224+
return (get, set);
2225+
}
2226+
2227+
private static readonly Regex codeTemplateAttributeRegex_ = new(@"@CSharpLua.Template\s*=\s*(.+)\s*", RegexOptions.Compiled);
2228+
private static readonly Regex codeGetAttributeRegex_ = new(@"@CSharpLua.Get\s*=\s*(.+)\s*", RegexOptions.Compiled);
2229+
private static readonly Regex codeSetAttributeRegex_ = new(@"@CSharpLua.Set\s*=\s*(.+)\s*", RegexOptions.Compiled);
2230+
2231+
private static string GetCodeTemplateFromAttributeText(string document, Regex regex) {
2232+
var matches = regex.Matches(document);
2233+
if (matches.Count > 0) {
2234+
string text = matches[0].Groups[1].Value;
2235+
return text.Trim().Trim('"');
2236+
}
2237+
return null;
2238+
}
2239+
2240+
public bool IsAutoProperty(IPropertySymbol symbol) {
2241+
var node = symbol.GetDeclaringSyntaxNode();
2242+
if (node != null) {
2243+
switch (node.Kind()) {
2244+
case SyntaxKind.PropertyDeclaration: {
2245+
var property = (PropertyDeclarationSyntax)node;
2246+
bool hasGet = false;
2247+
bool hasSet = false;
2248+
if (property.AccessorList != null) {
2249+
foreach (var accessor in property.AccessorList.Accessors) {
2250+
if (accessor.Body != null || accessor.ExpressionBody != null) {
2251+
if (accessor.IsKind(SyntaxKind.GetAccessorDeclaration)) {
2252+
Contract.Assert(!hasGet);
2253+
hasGet = true;
2254+
} else {
2255+
Contract.Assert(!hasSet);
2256+
hasSet = true;
2257+
}
2258+
}
2259+
}
2260+
} else {
2261+
Contract.Assert(!hasGet);
2262+
hasGet = true;
2263+
}
2264+
bool isField = !hasGet && !hasSet;
2265+
if (isField) {
2266+
if (HasCSharpLuaAttribute(property, LuaDocumentStatement.AttributeFlags.NoField)) {
2267+
isField = false;
2268+
}
2269+
}
2270+
return isField;
2271+
}
2272+
case SyntaxKind.IndexerDeclaration: {
2273+
return false;
2274+
}
2275+
case SyntaxKind.AnonymousObjectMemberDeclarator: {
2276+
return true;
2277+
}
2278+
case SyntaxKind.Parameter: {
2279+
return true;
2280+
}
2281+
default: {
2282+
throw new InvalidOperationException();
2283+
}
2284+
}
2285+
}
2286+
return false;
2287+
}
2288+
2289+
#endregion
21472290
}
21482291
}

CSharp.lua/LuaSyntaxNodeTransform.Object.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ public override LuaSyntaxNode VisitConstructorDeclaration(ConstructorDeclaration
439439
CurType.SetStaticCtor(function, document);
440440
} else {
441441
CurType.AddCtor(function, node.ParameterList.Parameters.Count == 0 || isCombineImplicitlyCtorMethod, document);
442-
bool isExportMetadata = IsCurTypeExportMetadataAll || attributes.Count > 0 || symbol.HasMetadataAttribute();
442+
bool isExportMetadata = IsCurTypeExportMetadataAll || attributes.Count > 0 || generator_.HasMetadataAttribute(symbol);
443443
if (isExportMetadata) {
444444
int ctorIndex = GetConstructorIndex(symbol);
445445
LuaIdentifierNameSyntax name;

CSharp.lua/LuaSyntaxNodeTransform.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ private MethodDeclarationResult BuildMethodDeclaration(
746746
function.AddParameter(parameter);
747747
if (parameterNode.Modifiers.IsOutOrRef()) {
748748
refOrOutParameters.Add(parameter);
749-
} else if (parameterNode.Modifiers.IsParams() && symbol.HasParamsAttribute()) {
749+
} else if (parameterNode.Modifiers.IsParams() && generator_.HasParamsAttribute(symbol)) {
750750
function.ParameterList.Parameters[^1] = LuaSyntaxNode.Tokens.Params;
751751
}
752752
}
@@ -807,8 +807,8 @@ private bool IsCurTypeSerializable {
807807
}
808808
}
809809

810-
private static bool IsExportMethodDeclaration(BaseMethodDeclarationSyntax node) {
811-
return (node.Body != null || node.ExpressionBody != null) && !node.HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Ignore);
810+
private bool IsExportMethodDeclaration(BaseMethodDeclarationSyntax node) {
811+
return (node.Body != null || node.ExpressionBody != null) && !generator_.HasCSharpLuaAttribute(node, LuaDocumentStatement.AttributeFlags.Ignore);
812812
}
813813

814814
public override LuaSyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) {
@@ -902,7 +902,7 @@ private void VisitBaseFieldDeclarationSyntax(BaseFieldDeclarationSyntax node) {
902902
bool isImmutable = typeSymbol.IsImmutable();
903903
foreach (var variable in node.Declaration.Variables) {
904904
var variableSymbol = semanticModel_.GetDeclaredSymbol(variable);
905-
if (variableSymbol.IsAbstract || variableSymbol.IsExtern || variableSymbol.GetDeclaringSyntaxNode().HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Ignore)) {
905+
if (variableSymbol.IsAbstract || variableSymbol.IsExtern || generator_.HasCSharpLuaAttribute(variableSymbol.GetDeclaringSyntaxNode(), LuaDocumentStatement.AttributeFlags.Ignore)) {
906906
continue;
907907
}
908908

@@ -917,7 +917,7 @@ private void VisitBaseFieldDeclarationSyntax(BaseFieldDeclarationSyntax node) {
917917
typeExpression = GetTypeName(eventSymbol.ContainingType);
918918
}
919919
var (add, remove) = CurType.AddEvent(eventName, innerName, valueExpression, isImmutable && valueIsLiteral, isStatic, eventSymbol.IsPrivate(), typeExpression, statements);
920-
if (attributes.Count > 0 || variableSymbol.HasMetadataAttribute()) {
920+
if (attributes.Count > 0 || generator_.HasMetadataAttribute(variableSymbol)) {
921921
AddPropertyOrEventMetaData(variableSymbol, new PropertyMethodResult(add), new PropertyMethodResult(remove), null, attributes);
922922
}
923923
continue;
@@ -933,7 +933,7 @@ private void VisitBaseFieldDeclarationSyntax(BaseFieldDeclarationSyntax node) {
933933
isMoreThanUpValueStaticInit = IsMoreThanUpValueStaticInitField(variableSymbol);
934934
}
935935
AddField(fieldName, typeSymbol, value, isImmutable, isStatic, isPrivate, isReadOnly, isMoreThanLocalVariables, isMoreThanUpValueStaticInit);
936-
if (IsCurTypeSerializable || attributes.Count > 0 || variableSymbol.HasMetadataAttribute()) {
936+
if (IsCurTypeSerializable || attributes.Count > 0 || generator_.HasMetadataAttribute(variableSymbol)) {
937937
if (variableSymbol.Kind == SymbolKind.Field) {
938938
AddFieldMetaData((IFieldSymbol)variableSymbol, fieldName, attributes);
939939
} else {
@@ -1064,7 +1064,7 @@ private void AddPropertyOrEventMetaData(ISymbol symbol, PropertyMethodResult get
10641064

10651065
public override LuaSyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) {
10661066
var symbol = semanticModel_.GetDeclaredSymbol(node);
1067-
if (!symbol.IsAbstract && !symbol.IsExtern && !symbol.GetDeclaringSyntaxNode().HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Ignore)) {
1067+
if (!symbol.IsAbstract && !symbol.IsExtern && !generator_.HasCSharpLuaAttribute(symbol.GetDeclaringSyntaxNode(), LuaDocumentStatement.AttributeFlags.Ignore)) {
10681068
bool isStatic = symbol.IsStatic;
10691069
bool isPrivate = generator_.IsPrivate(symbol) && symbol.ExplicitInterfaceImplementations.IsEmpty;
10701070
bool hasGet = false;
@@ -1162,7 +1162,7 @@ public override LuaSyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax
11621162
}
11631163
}
11641164

1165-
if (IsCurTypeSerializable || attributes.Count > 0 || symbol.HasMetadataAttribute()) {
1165+
if (IsCurTypeSerializable || attributes.Count > 0 || generator_.HasMetadataAttribute(symbol)) {
11661166
AddPropertyOrEventMetaData(symbol, getMethod, setMethod, propertyName, attributes);
11671167
}
11681168
}
@@ -1176,7 +1176,7 @@ private bool IsReadOnlyProperty(PropertyDeclarationSyntax node) {
11761176

11771177
public override LuaSyntaxNode VisitEventDeclaration(EventDeclarationSyntax node) {
11781178
var symbol = semanticModel_.GetDeclaredSymbol(node);
1179-
if (!symbol.IsAbstract && !symbol.IsExtern && !symbol.GetDeclaringSyntaxNode().HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Ignore)) {
1179+
if (!symbol.IsAbstract && !symbol.IsExtern && !generator_.HasCSharpLuaAttribute(symbol.GetDeclaringSyntaxNode(), LuaDocumentStatement.AttributeFlags.Ignore)) {
11801180
var attributes = BuildAttributes(node.AttributeLists);
11811181
bool isStatic = symbol.IsStatic;
11821182
bool isPrivate = symbol.IsPrivate() && symbol.ExplicitInterfaceImplementations.IsEmpty;
@@ -1209,7 +1209,7 @@ public override LuaSyntaxNode VisitEventDeclaration(EventDeclarationSyntax node)
12091209
}
12101210
}
12111211

1212-
if (attributes.Count > 0 || symbol.HasMetadataAttribute()) {
1212+
if (attributes.Count > 0 || generator_.HasMetadataAttribute(symbol)) {
12131213
AddPropertyOrEventMetaData(symbol, addMethod, removeMethod, null, attributes);
12141214
}
12151215
}
@@ -1226,7 +1226,7 @@ public override LuaSyntaxNode VisitEnumMemberDeclaration(EnumMemberDeclarationSy
12261226
Contract.Assert(symbol.HasConstantValue);
12271227
LuaIdentifierNameSyntax identifier = node.Identifier.ValueText;
12281228
var attributes = BuildAttributes(node.AttributeLists);
1229-
if (IsCurTypeSerializable || attributes.Count > 0 || CurTypeSymbol.HasMetadataAttribute()) {
1229+
if (IsCurTypeSerializable || attributes.Count > 0 || generator_.HasMetadataAttribute(CurTypeSymbol)) {
12301230
AddFieldMetaData(symbol, identifier, attributes);
12311231
}
12321232
var value = new LuaIdentifierLiteralExpressionSyntax(symbol.ConstantValue.ToString());
@@ -1235,7 +1235,7 @@ public override LuaSyntaxNode VisitEnumMemberDeclaration(EnumMemberDeclarationSy
12351235

12361236
public override LuaSyntaxNode VisitIndexerDeclaration(IndexerDeclarationSyntax node) {
12371237
var symbol = semanticModel_.GetDeclaredSymbol(node);
1238-
if (!symbol.IsAbstract && !symbol.IsExtern && !symbol.GetDeclaringSyntaxNode().HasCSharpLuaAttribute(LuaDocumentStatement.AttributeFlags.Ignore)) {
1238+
if (!symbol.IsAbstract && !symbol.IsExtern && !generator_.HasCSharpLuaAttribute(symbol.GetDeclaringSyntaxNode(), LuaDocumentStatement.AttributeFlags.Ignore)) {
12391239
bool isPrivate = symbol.IsPrivate();
12401240
var indexName = GetMemberName(symbol);
12411241
var parameterList = node.ParameterList.Accept<LuaParameterListSyntax>(this);
@@ -2479,7 +2479,7 @@ private void CheckInvocationDefaultArguments(
24792479
}
24802480
} else if (!parameters.IsEmpty) {
24812481
IParameterSymbol last = parameters.Last();
2482-
if (last.IsParams && generator_.IsFromLuaModule(symbol) && !symbol.HasParamsAttribute()) {
2482+
if (last.IsParams && generator_.IsFromLuaModule(symbol) && !generator_.HasParamsAttribute(symbol)) {
24832483
if (parameters.Length == arguments.Count) {
24842484
var paramsArgument = argumentNodeInfos.Last();
24852485
if (paramsArgument.Name != null) {
@@ -2905,7 +2905,7 @@ private bool IsEventAddOrRemoveIdentifierName(IdentifierNameSyntax node) {
29052905
}
29062906

29072907
private bool IsPropertyField(IdentifierNameSyntax node, IPropertySymbol propertySymbol) {
2908-
return IsPropertyField(propertySymbol) || (IsInternalNode(node) && propertySymbol.IsAutoProperty());
2908+
return IsPropertyField(propertySymbol) || (IsInternalNode(node) && generator_.IsAutoProperty(propertySymbol));
29092909
}
29102910

29112911
private LuaExpressionSyntax VisitPropertyOrEventIdentifierName(IdentifierNameSyntax node, ISymbol symbol, bool isProperty, out bool isField) {
@@ -2915,7 +2915,7 @@ private LuaExpressionSyntax VisitPropertyOrEventIdentifierName(IdentifierNameSyn
29152915
isField = IsPropertyField(node, propertySymbol);
29162916
isReadOnly = propertySymbol.IsReadOnly;
29172917
if (IsPropertyTemplate(propertySymbol)) {
2918-
var (get, set) = Utility.GetPropertyTemplateFromAttribute(symbol);
2918+
var (get, set) = generator_.GetPropertyTemplateFromAttribute(symbol);
29192919
return new LuaPropertyTemplateExpressionSyntax(get, set);
29202920
}
29212921
} else {
@@ -3322,7 +3322,7 @@ LuaIdentifierNameSyntax GetSampleName(ISymbol nodeSymbol) {
33223322
}
33233323
case SymbolKind.Field: {
33243324
var fieldSymbol = (IFieldSymbol)symbol;
3325-
var codeTemplate = fieldSymbol.GetCodeTemplateFromAttribute();
3325+
var codeTemplate = generator_.GetCodeTemplateFromAttribute(fieldSymbol);
33263326
if (codeTemplate != null) {
33273327
identifier = BuildCodeTemplateExpression(codeTemplate, fieldSymbol.IsStatic ? null : LuaIdentifierNameSyntax.This);
33283328
break;

0 commit comments

Comments
 (0)