提交 4d04cdc8 编写于 作者: A AlekseyTs

Finalizing Syntax Model for Out Variable Declarations.

Adjusted behavior of CSharpSyntaxGenerator and added some explicitly written code to achieve the following for the Syntax Model:
- Factory static ArgumentSyntax Argument(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration) will be internal.
- Factory static ArgumentSyntax Argument(CSharpSyntaxNode expressionOrDeclaration) will be internal.
- There will be the following public factories:
public static ArgumentSyntax Argument(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, ExpressionSyntax expression)
public static ArgumentSyntax Argument(ExpressionSyntax expression)
public static ArgumentSyntax Argument(NameColonSyntax nameColon, SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
public static ArgumentSyntax Argument(SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
- Update method ArgumentSyntax Update(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration) will be internal.
- There will be the following public update methods:
public ArgumentSyntax Update(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, ExpressionSyntax expression)
public ArgumentSyntax Update(NameColonSyntax nameColon, SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
- With method ArgumentSyntax WithExpressionOrDeclaration(CSharpSyntaxNode expressionOrDeclaration) will be internal.
- There will be the following public With methods:
public ArgumentSyntax WithNameColon(NameColonSyntax nameColon)
public ArgumentSyntax WithRefOrOutKeyword(SyntaxToken refOrOutKeyword)
public ArgumentSyntax WithExpression(ExpressionSyntax expression)
public ArgumentSyntax WithDeclaration(VariableDeclarationSyntax declaration)
- Property CSharpSyntaxNode ExpressionOrDeclaration will be internal.
- Instead there will be the following public properties (one of them will return null depending on the value of ExpressionOrDeclaration):
public ExpressionSyntax Expression
public VariableDeclarationSyntax Declaration
- Factory, Update and With methods should provide stronger validation:
a) ExpressionOrDeclaration must either be an ExpressionSyntax, or a VariableDeclarationSyntax;
b) Declaration must be combined with out keyword;
c) Declaration must have single VariableDeclarator;
d) VariableDeclarator must have null ArgumentList and null Initializer.
上级 cdd41d43
......@@ -526,7 +526,7 @@ public SymbolInfo GetSymbolInfo(ExpressionSyntax expression, CancellationToken c
(parent = parent.Parent)?.Kind() == SyntaxKind.Argument &&
((ArgumentSyntax)parent).Type == expression)
{
TypeSymbol outVarType = (GetDeclaredSymbol(((ArgumentSyntax)parent).VariableDeclaration.Variables.First(), cancellationToken) as LocalSymbol)?.Type;
TypeSymbol outVarType = (GetDeclaredSymbol(((ArgumentSyntax)parent).Declaration.Variables.First(), cancellationToken) as LocalSymbol)?.Type;
if (outVarType?.IsErrorType() == false)
{
......
Microsoft.CodeAnalysis.CSharp.Conversion.IsTuple.get -> bool
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.ExpressionOrDeclaration.get -> Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.Declaration.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.NameColonSyntax nameColon, Microsoft.CodeAnalysis.SyntaxToken outKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.NameColonSyntax nameColon, Microsoft.CodeAnalysis.SyntaxToken refOrOutKeyword, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode expressionOrDeclaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.VariableDeclaration.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.WithExpressionOrDeclaration(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode expressionOrDeclaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax.WithDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax.RefKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken arrowToken, Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax.WithRefKeyword(Microsoft.CodeAnalysis.SyntaxToken refKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax
......@@ -175,9 +173,7 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax.Accept<TResult>(M
static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(this Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax declarationSyntax, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.ISymbol
static Microsoft.CodeAnalysis.CSharp.SyntaxExtensions.Update(this Microsoft.CodeAnalysis.CSharp.Syntax.IndexerDeclarationSyntax syntax, Microsoft.CodeAnalysis.SyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax> attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken thisKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.BracketedParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.AccessorListSyntax accessorList) -> Microsoft.CodeAnalysis.CSharp.Syntax.IndexerDeclarationSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxExtensions.Update(this Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax syntax, Microsoft.CodeAnalysis.SyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax> attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.CSharp.Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.SyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterConstraintClauseSyntax> constraintClauses, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax block, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Argument(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode expressionOrDeclaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Argument(Microsoft.CodeAnalysis.CSharp.Syntax.NameColonSyntax nameColon, Microsoft.CodeAnalysis.SyntaxToken outKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Argument(Microsoft.CodeAnalysis.CSharp.Syntax.NameColonSyntax nameColon, Microsoft.CodeAnalysis.SyntaxToken refOrOutKeyword, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode expressionOrDeclaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Argument(Microsoft.CodeAnalysis.SyntaxToken outKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ArrowExpressionClause(Microsoft.CodeAnalysis.SyntaxToken arrowToken, Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CasePatternSwitchLabel(Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern, Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax whenClause, Microsoft.CodeAnalysis.SyntaxToken colonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax
......
......@@ -8,39 +8,41 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax
public partial class ArgumentSyntax
{
/// <summary>
/// Get expression representing the value of the argument.
/// Get expression representing the value of the argument, or null if arguments declares
/// an out variable.
/// </summary>
public ExpressionSyntax Expression
{
get
{
if (RefOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
{
return (ExpressionSyntax)ExpressionOrDeclaration;
}
return ExpressionOrDeclaration as ExpressionSyntax;
}
}
public ArgumentSyntax WithExpression(ExpressionSyntax expression)
{
return this.Update(this.NameColon, this.RefOrOutKeyword, expression);
return this.WithExpressionOrDeclaration(expression);
}
public ArgumentSyntax WithDeclaration(VariableDeclarationSyntax declaration)
{
if (this.RefOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
{
throw new InvalidOperationException();
}
return this.WithExpressionOrDeclaration(declaration);
}
/// <summary>
/// Get declaration of an Out Variable for the argument.
/// Get declaration of an Out Variable for the argument, or null
/// if it doesn't declare any.
/// </summary>
public VariableDeclarationSyntax VariableDeclaration
public VariableDeclarationSyntax Declaration
{
get
{
if (RefOrOutKeyword.Kind() != SyntaxKind.OutKeyword || ExpressionOrDeclaration.Kind() != SyntaxKind.VariableDeclaration)
{
return null;
}
return (VariableDeclarationSyntax)ExpressionOrDeclaration;
return ExpressionOrDeclaration as VariableDeclarationSyntax;
}
}
......@@ -51,7 +53,7 @@ internal SyntaxToken Identifier
{
get
{
VariableDeclarationSyntax declaration = VariableDeclaration;
VariableDeclarationSyntax declaration = Declaration;
if (declaration != null)
{
return declaration.Variables.First().Identifier;
......@@ -68,7 +70,7 @@ internal TypeSyntax Type
{
get
{
VariableDeclarationSyntax declaration = VariableDeclaration;
VariableDeclarationSyntax declaration = Declaration;
if (declaration != null)
{
return declaration.Type;
......@@ -85,16 +87,6 @@ public ArgumentSyntax Update(NameColonSyntax nameColon, SyntaxToken refOrOutKeyw
public ArgumentSyntax Update(NameColonSyntax nameColon, SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
{
if (outKeyword.Kind() != SyntaxKind.OutKeyword)
{
throw new ArgumentException(nameof(outKeyword));
}
if (declaration != null && !IsValidOutVariableDeclaration(declaration))
{
throw new ArgumentException(nameof(declaration));
}
return this.Update(nameColon, outKeyword, (CSharpSyntaxNode)declaration);
}
......@@ -126,5 +118,13 @@ internal static bool IsIdentifierOfOutVariableDeclaration(SyntaxToken identifier
declaringArgument = null;
return false;
}
partial void ValidateWithRefOrOutKeywordInput(SyntaxToken refOrOutKeyword)
{
if (ExpressionOrDeclaration.Kind() == SyntaxKind.VariableDeclaration && refOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
{
throw new ArgumentException(nameof(refOrOutKeyword));
}
}
}
}
......@@ -1101,7 +1101,7 @@
<summary>SyntaxToken representing the optional ref or out keyword.</summary>
</PropertyComment>
</Field>
<Field Name="ExpressionOrDeclaration" Type="CSharpSyntaxNode" >
<Field Name="ExpressionOrDeclaration" Type="CSharpSyntaxNode" Internal="true">
<PropertyComment>
<summary>
ExpressionSyntax node representing the argument value,
......
......@@ -2529,23 +2529,81 @@ public static ArgumentSyntax Argument(ExpressionSyntax expression)
/// <summary>Creates a new ArgumentSyntax instance.</summary>
public static ArgumentSyntax Argument(NameColonSyntax nameColon, SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
{
if (outKeyword.Kind() != SyntaxKind.OutKeyword)
return Argument(nameColon, outKeyword, (CSharpSyntaxNode)declaration);
}
/// <summary>Creates a new ArgumentSyntax instance.</summary>
public static ArgumentSyntax Argument(SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
{
return Argument(default(NameColonSyntax), outKeyword, declaration);
}
static partial void ValidateArgumentParts(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration)
{
if (expressionOrDeclaration.Kind() == SyntaxKind.VariableDeclaration)
{
throw new ArgumentException(nameof(outKeyword));
}
if (refOrOutKeyword.Kind() != SyntaxKind.OutKeyword)
{
throw new ArgumentException("outKeyword");
}
if (declaration != null && !ArgumentSyntax.IsValidOutVariableDeclaration(declaration))
if (!ArgumentSyntax.IsValidOutVariableDeclaration((VariableDeclarationSyntax)expressionOrDeclaration))
{
throw new ArgumentException("declaration");
}
}
else if (!(expressionOrDeclaration is ExpressionSyntax))
{
throw new ArgumentException(nameof(declaration));
throw new ArgumentException(nameof(expressionOrDeclaration));
}
}
}
}
return Argument(nameColon, outKeyword, (CSharpSyntaxNode)declaration);
namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax
{
internal static partial class SyntaxFactory
{
#if DEBUG
static partial void ValidateArgumentParts(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration)
{
ValidateArgumentPartsImpl(nameColon, refOrOutKeyword, expressionOrDeclaration);
}
/// <summary>Creates a new ArgumentSyntax instance.</summary>
public static ArgumentSyntax Argument(SyntaxToken outKeyword, VariableDeclarationSyntax declaration)
static public void ValidateArgumentPartsImpl(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration)
{
return Argument(default(NameColonSyntax), outKeyword, declaration);
if (expressionOrDeclaration.Kind == SyntaxKind.VariableDeclaration)
{
if (refOrOutKeyword.Kind != SyntaxKind.OutKeyword)
{
throw new ArgumentException(nameof(refOrOutKeyword));
}
var declaration = (VariableDeclarationSyntax)expressionOrDeclaration;
if (!(declaration.Variables.Count == 1 &&
declaration.Variables[0].ArgumentList == null &&
declaration.Variables[0].Initializer == null))
{
throw new ArgumentException(nameof(expressionOrDeclaration));
}
}
else if (!(expressionOrDeclaration is ExpressionSyntax))
{
throw new ArgumentException(nameof(expressionOrDeclaration));
}
}
#endif
}
internal partial class ContextAwareSyntax
{
#if DEBUG
partial void ValidateArgumentParts(NameColonSyntax nameColon, SyntaxToken refOrOutKeyword, CSharpSyntaxNode expressionOrDeclaration)
{
SyntaxFactory.ValidateArgumentPartsImpl(nameColon, refOrOutKeyword, expressionOrDeclaration);
}
#endif
}
}
......@@ -110,6 +110,11 @@ protected static string OverrideOrNewModifier(Field field)
return IsOverride(field) ? "override " : IsNew(field) ? "new " : "";
}
protected static string AccessibilityModifier(Field field)
{
return IsInternal(field) ? "internal" : "public";
}
protected static bool CanBeField(Field field)
{
return field.Type != "SyntaxToken" && !IsAnyList(field.Type) && !IsOverride(field) && !IsNew(field);
......@@ -204,6 +209,11 @@ protected static bool IsOverride(Field f)
return f.Override != null && string.Compare(f.Override, "true", true) == 0;
}
protected static bool IsInternal(Field f)
{
return f.Internal != null && string.Compare(f.Internal, "true", true) == 0;
}
protected static bool IsNew(Field f)
{
return f.New != null && string.Compare(f.New, "true", true) == 0;
......
......@@ -22,6 +22,9 @@ public class Field
[XmlAttribute]
public string New;
[XmlAttribute]
public string Internal;
[XmlElement(ElementName = "Kind", Type = typeof(Kind))]
public List<Kind> Kinds;
......
......@@ -626,7 +626,7 @@ private void WriteContextualGreenFactories()
{
var nodes = Tree.Types.Where(n => !(n is PredefinedNode) && !(n is AbstractNode)).ToList();
WriteLine();
WriteLine(" internal class ContextAwareSyntax");
WriteLine(" internal partial class ContextAwareSyntax");
WriteLine(" {");
WriteLine();
......@@ -695,24 +695,9 @@ private void WriteGreenFactory(Node nd, bool withSyntaxFactoryContext = false)
{
var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList();
var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList();
bool anyList = false;
Write(" public {0}{1} {2}(", withSyntaxFactoryContext ? "" : "static ", nd.Name, StripPost(nd.Name, "Syntax"));
if (nd.Kinds.Count > 1)
{
Write("SyntaxKind kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
anyList |= IsAnyList(field.Type);
var type = field.Type;
if (type == "SyntaxNodeOrTokenList")
type = "SyntaxList<CSharpSyntaxNode>";
Write("{0} {1}", type, CamelCase(field.Name));
}
WriteGreenFactoryParameters(nd);
WriteLine(")");
WriteLine(" {");
......@@ -771,6 +756,22 @@ private void WriteGreenFactory(Node nd, bool withSyntaxFactoryContext = false)
}
}
}
// Call custom validator
Write(" Validate{0}Parts(", StripPost(nd.Name, "Syntax"));
if (nd.Kinds.Count > 1)
{
Write("kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
Write("{0}", CamelCase(field.Name));
}
WriteLine(");");
WriteLine("#endif");
......@@ -828,6 +829,32 @@ private void WriteGreenFactory(Node nd, bool withSyntaxFactoryContext = false)
}
WriteLine(" }");
// Declare custom validator
WriteLine();
WriteLine("#if DEBUG");
Write(" {0}partial void Validate{1}Parts(", withSyntaxFactoryContext ? "" : "static ", StripPost(nd.Name, "Syntax"));
WriteGreenFactoryParameters(nd);
WriteLine(");");
WriteLine("#endif");
}
private void WriteGreenFactoryParameters(Node nd)
{
if (nd.Kinds.Count > 1)
{
Write("SyntaxKind kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
var type = field.Type;
if (type == "SyntaxNodeOrTokenList")
type = "SyntaxList<CSharpSyntaxNode>";
Write("{0} {1}", type, CamelCase(field.Name));
}
}
private void WriteCtorArgList(Node nd, bool withSyntaxFactoryContext, List<Field> valueFields, List<Field> nodeFields)
......@@ -904,7 +931,7 @@ private void WriteRedType(TreeType node)
var fieldType = field.Type == "SyntaxList<SyntaxToken>" ? "SyntaxTokenList" : field.Type;
WriteLine();
WriteComment(field.PropertyComment, " ");
WriteLine(" public abstract {0}{1} {2} {{ get; }}", (IsNew(field) ? "new " : ""), fieldType, field.Name);
WriteLine(" {0} abstract {1}{2} {3} {{ get; }}", AccessibilityModifier(field), (IsNew(field) ? "new " : ""), fieldType, field.Name);
}
}
......@@ -913,7 +940,7 @@ private void WriteRedType(TreeType node)
var field = valueFields[i];
WriteLine();
WriteComment(field.PropertyComment, " ");
WriteLine(" public abstract {0}{1} {2} {{ get; }}", (IsNew(field) ? "new " : ""), field.Type, field.Name);
WriteLine(" {0} abstract {1}{2} {3} {{ get; }}", AccessibilityModifier(field), (IsNew(field) ? "new " : ""), field.Type, field.Name);
}
WriteLine(" }");
......@@ -961,7 +988,7 @@ private void WriteRedType(TreeType node)
if (field.Type == "SyntaxToken")
{
WriteComment(field.PropertyComment, " ");
WriteLine(" public {0}{1} {2} ", OverrideOrNewModifier(field), field.Type, field.Name);
WriteLine(" {0} {1}{2} {3} ", AccessibilityModifier(field), OverrideOrNewModifier(field), field.Type, field.Name);
WriteLine(" {");
if (IsOptional(field))
{
......@@ -983,7 +1010,7 @@ private void WriteRedType(TreeType node)
else if (field.Type == "SyntaxList<SyntaxToken>")
{
WriteComment(field.PropertyComment, " ");
WriteLine(" public {0}SyntaxTokenList {1} ", OverrideOrNewModifier(field), field.Name);
WriteLine(" {0} {1}SyntaxTokenList {2} ", AccessibilityModifier(field), OverrideOrNewModifier(field), field.Name);
WriteLine(" {");
WriteLine(" get");
WriteLine(" {");
......@@ -998,7 +1025,7 @@ private void WriteRedType(TreeType node)
else
{
WriteComment(field.PropertyComment, " ");
WriteLine(" public {0}{1} {2} ", OverrideOrNewModifier(field), field.Type, field.Name);
WriteLine(" {0} {1}{2} {3} ", AccessibilityModifier(field), OverrideOrNewModifier(field), field.Type, field.Name);
WriteLine(" {");
WriteLine(" get");
WriteLine(" {");
......@@ -1040,8 +1067,8 @@ private void WriteRedType(TreeType node)
{
var field = valueFields[i];
WriteComment(field.PropertyComment, " ");
WriteLine(" public {0}{1} {2} {{ get {{ return ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{3})this.Green).{2}; }} }}",
OverrideOrNewModifier(field), field.Type, field.Name, node.Name
WriteLine(" {0} {1}{2} {3} {{ get {{ return ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{4})this.Green).{3}; }} }}",
AccessibilityModifier(field), OverrideOrNewModifier(field), field.Type, field.Name, node.Name
);
WriteLine();
}
......@@ -1181,7 +1208,7 @@ private void WriteRedVisitor(bool genericArgument, bool genericResult)
private void WriteRedUpdateMethod(Node node)
{
WriteLine();
Write(" public {0} Update(", node.Name);
Write(" {0} {1} Update(", node.Fields.Any(f => IsInternal(f)) ? "internal" : "public", node.Name);
// parameters
for (int f = 0; f < node.Fields.Count; f++)
......@@ -1280,10 +1307,11 @@ private void WriteRedSetters(Node node)
var type = this.GetRedPropertyType(field);
WriteLine();
WriteLine(" public {0} With{1}({2} {3})", node.Name, StripPost(field.Name, "Opt"), type, CamelCase(field.Name));
WriteLine(" {0} {1} With{2}({3} {4})", AccessibilityModifier(field), node.Name, StripPost(field.Name, "Opt"), type, CamelCase(field.Name));
WriteLine(" {");
//WriteLine(" return this.With({0}: {0});", CamelCase(field.Name));
// call custom validator
WriteLine(" ValidateWith{0}Input({1});", StripPost(field.Name, "Opt"), CamelCase(field.Name));
// call update inside each setter
Write(" return this.Update(");
......@@ -1305,6 +1333,10 @@ private void WriteRedSetters(Node node)
WriteLine(");");
WriteLine(" }");
// Declare the custom validator
WriteLine();
WriteLine(" partial void ValidateWith{0}Input({1} {2});", StripPost(field.Name, "Opt"), type, CamelCase(field.Name));
}
}
......@@ -1531,21 +1563,8 @@ private void WriteRedFactory(Node nd)
WriteComment(string.Format("<summary>Creates a new {0} instance.</summary>", nd.Name), " ");
Write(" public static {0} {1}(", nd.Name, StripPost(nd.Name, "Syntax"));
if (nd.Kinds.Count > 1)
{
Write("SyntaxKind kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
var type = this.GetRedPropertyType(field);
Write("{0} {1}", type, CamelCase(field.Name));
}
Write(" {0} static {1} {2}(", nd.Fields.Any(f => IsInternal(f)) ? "internal" : "public", nd.Name, StripPost(nd.Name, "Syntax"));
WriteRedFactoryParameters(nd);
WriteLine(")");
WriteLine(" {");
......@@ -1598,6 +1617,23 @@ private void WriteRedFactory(Node nd)
}
}
// Call custom validator
Write(" Validate{0}Parts(", StripPost(nd.Name, "Syntax"));
if (nd.Kinds.Count > 1)
{
Write("kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
Write("{0}", CamelCase(field.Name));
}
WriteLine(");");
Write(" return ({0})Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.SyntaxFactory.{1}(", nd.Name, StripPost(nd.Name, "Syntax"));
if (nd.Kinds.Count > 1)
{
......@@ -1644,6 +1680,31 @@ private void WriteRedFactory(Node nd)
WriteLine(").CreateRed();");
WriteLine(" }");
this.WriteLine();
// Add partial definition for a custom validator
Write(" static partial void Validate{0}Parts(", StripPost(nd.Name, "Syntax"));
WriteRedFactoryParameters(nd);
WriteLine(");");
}
private void WriteRedFactoryParameters(Node nd)
{
if (nd.Kinds.Count > 1)
{
Write("SyntaxKind kind, ");
}
for (int i = 0, n = nd.Fields.Count; i < n; i++)
{
var field = nd.Fields[i];
if (i > 0)
Write(", ");
var type = this.GetRedPropertyType(field);
Write("{0} {1}", type, CamelCase(field.Name));
}
}
private string GetRedPropertyType(Field field)
......@@ -1734,7 +1795,7 @@ private void WriteRedFactoryWithNoAutoCreatableTokens(Node nd)
this.WriteLine();
WriteComment(string.Format("<summary>Creates a new {0} instance.</summary>", nd.Name), " ");
Write(" public static {0} {1}(", nd.Name, StripPost(nd.Name, "Syntax"));
Write(" {0} static {1} {2}(", factoryWithNoAutoCreatableTokenFields.Any(f => IsInternal(f)) ? "internal" : "public", nd.Name, StripPost(nd.Name, "Syntax"));
bool hasPreviousParameter = false;
if (nd.Kinds.Count > 1)
......@@ -1855,7 +1916,7 @@ private void WriteRedMinimalFactory(Node nd, bool withStringNames = false)
this.WriteLine();
WriteComment(string.Format("<summary>Creates a new {0} instance.</summary>", nd.Name), " ");
Write(" public static {0} {1}(", nd.Name, StripPost(nd.Name, "Syntax"));
Write(" {0} static {1} {2}(", minimalFactoryfields.Any(f => IsInternal(f)) ? "internal" : "public", nd.Name, StripPost(nd.Name, "Syntax"));
bool hasPreviousParameter = false;
if (nd.Kinds.Count > 1)
......
......@@ -1201,7 +1201,7 @@ public static bool IsParameterTypeContext(this SyntaxTree syntaxTree, int positi
if (token.IsKind(SyntaxKind.OutKeyword) &&
token.Parent.IsKind(SyntaxKind.Argument) &&
((ArgumentSyntax)token.Parent).VariableDeclaration != null)
((ArgumentSyntax)token.Parent).Declaration != null)
{
return true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册