Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/NRefactory.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Grunwald <daniel@danielgrunwald.de>2016-11-25 20:02:14 +0300
committerDaniel Grunwald <daniel@danielgrunwald.de>2016-11-25 20:02:14 +0300
commit3c638f6c43d77922e4a14c5af1b224e9563236f2 (patch)
treee2bf12fadee7de8b795a53f30df9e2a99516110b
parent2b10193ea20a26ae9c8db21a79c60f3be8d8cca8 (diff)
Add 'ref T' AstType syntax node. This allows generating code for C# 7 'ref locals' and 'ref return'.
-rw-r--r--ICSharpCode.NRefactory.CSharp/Ast/AstType.cs10
-rw-r--r--ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs35
-rw-r--r--ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs3
-rw-r--r--ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs9
-rw-r--r--ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs3
5 files changed, 55 insertions, 5 deletions
diff --git a/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
index 2f13f0fd..80ca72ac 100644
--- a/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
+++ b/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
@@ -209,7 +209,15 @@ namespace ICSharpCode.NRefactory.CSharp
{
return new ComposedType { BaseType = this, HasNullableSpecifier = true };
}
-
+
+ /// <summary>
+ /// Creates a C# 7 ref type from this type by nesting it in a <see cref="ComposedType"/>.
+ /// </summary>
+ public virtual AstType MakeRefType()
+ {
+ return new ComposedType { BaseType = this, HasRefSpecifier = true };
+ }
+
/// <summary>
/// Builds an expression that can be used to access a static member on this type.
/// </summary>
diff --git a/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs b/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
index 0c0f96c6..2bbfc5a8 100644
--- a/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
+++ b/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
@@ -33,10 +33,25 @@ namespace ICSharpCode.NRefactory.CSharp
{
public class ComposedType : AstType
{
+ public static readonly TokenRole RefRole = new TokenRole("ref");
public static readonly TokenRole NullableRole = new TokenRole("?");
public static readonly TokenRole PointerRole = new TokenRole("*");
public static readonly Role<ArraySpecifier> ArraySpecifierRole = new Role<ArraySpecifier>("ArraySpecifier");
-
+
+ /// <summary>
+ /// Gets/sets whether this type has a 'ref' specifier.
+ /// This is used for C# 7 ref locals/ref return.
+ /// Parameters use ParameterDeclaration.ParameterModifier instead.
+ /// </summary>
+ public bool HasRefSpecifier {
+ get {
+ return !GetChildByRole(RefRole).IsNull;
+ }
+ set {
+ SetChildByRole(RefRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null);
+ }
+ }
+
public AstType BaseType {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
@@ -102,7 +117,10 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ComposedType o = other as ComposedType;
- return o != null && this.HasNullableSpecifier == o.HasNullableSpecifier && this.PointerRank == o.PointerRank
+ return o != null
+ && this.HasNullableSpecifier == o.HasNullableSpecifier
+ && this.PointerRank == o.PointerRank
+ && this.HasRefSpecifier == o.HasRefSpecifier
&& this.BaseType.DoMatch(o.BaseType, match)
&& this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match);
}
@@ -110,6 +128,8 @@ namespace ICSharpCode.NRefactory.CSharp
public override string ToString(CSharpFormattingOptions formattingOptions)
{
StringBuilder b = new StringBuilder();
+ if (this.HasRefSpecifier)
+ b.Append("ref ");
b.Append(this.BaseType.ToString());
if (this.HasNullableSpecifier)
b.Append('?');
@@ -137,7 +157,13 @@ namespace ICSharpCode.NRefactory.CSharp
InsertChildBefore(this.ArraySpecifiers.FirstOrDefault(), new ArraySpecifier(dimensions), ArraySpecifierRole);
return this;
}
-
+
+ public override AstType MakeRefType()
+ {
+ this.HasRefSpecifier = true;
+ return this;
+ }
+
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
{
if (interningProvider == null)
@@ -153,6 +179,9 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (var a in this.ArraySpecifiers.Reverse()) {
t = interningProvider.Intern(new ArrayTypeReference(t, a.Dimensions));
}
+ if (this.HasRefSpecifier) {
+ t = interningProvider.Intern(new ByReferenceTypeReference(t));
+ }
return t;
}
}
diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
index 769c4e09..683a632e 100644
--- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
+++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
@@ -2146,6 +2146,9 @@ namespace ICSharpCode.NRefactory.CSharp
public virtual void VisitComposedType(ComposedType composedType)
{
StartNode(composedType);
+ if (composedType.HasRefSpecifier) {
+ WriteKeyword(ComposedType.RefRole);
+ }
composedType.BaseType.AcceptVisitor(this);
if (composedType.HasNullableSpecifier) {
WriteToken(ComposedType.NullableRole);
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs
index 5badd658..476ab8dc 100644
--- a/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs
@@ -217,6 +217,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return ConvertType(typeWithElementType.ElementType).MakePointerType();
} else if (typeWithElementType is ArrayType) {
return ConvertType(typeWithElementType.ElementType).MakeArrayType(((ArrayType)type).Dimensions);
+ } else if (typeWithElementType is ByReferenceType) {
+ return ConvertType(typeWithElementType.ElementType).MakeRefType();
} else {
// e.g. ByReferenceType; not supported as type in C#
return ConvertType(typeWithElementType.ElementType);
@@ -584,7 +586,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (ShowAttributes) {
decl.Attributes.AddRange (parameter.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
}
- decl.Type = ConvertType(parameter.Type);
+ if (parameter.Type.Kind == TypeKind.ByReference) {
+ // avoid 'out ref'
+ decl.Type = ConvertType(((ByReferenceType)parameter.Type).ElementType);
+ } else {
+ decl.Type = ConvertType(parameter.Type);
+ }
if (this.ShowParameterNames) {
decl.Name = parameter.Name;
}
diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
index 340b290e..27a28660 100644
--- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
+++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
@@ -3379,6 +3379,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var a in composedType.ArraySpecifiers.Reverse()) {
t = new ArrayType(resolver.Compilation, t, a.Dimensions);
}
+ if (composedType.HasRefSpecifier) {
+ t = new ByReferenceType(t);
+ }
return new TypeResolveResult(t);
}
#endregion