Browse Source

Updated mcs/fixed unit test.

string literal constants now contain the real 'literal'.
newNRvisualizers
Mike Krüger 15 years ago
parent
commit
8b606d1b32
  1. 2
      ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs
  2. 32
      ICSharpCode.NRefactory/CSharp/Parser/mcs/anonymous.cs
  3. 313
      ICSharpCode.NRefactory/CSharp/Parser/mcs/async.cs
  4. 2
      ICSharpCode.NRefactory/CSharp/Parser/mcs/context.cs
  5. 9350
      ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-parser.cs
  6. 94
      ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-parser.jay
  7. 75
      ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-tokenizer.cs
  8. 1
      ICSharpCode.NRefactory/CSharp/Parser/mcs/decl.cs
  9. 6
      ICSharpCode.NRefactory/CSharp/Parser/mcs/generic.cs
  10. 36
      ICSharpCode.NRefactory/CSharp/Parser/mcs/iterators.cs
  11. 7
      ICSharpCode.NRefactory/CSharp/Parser/mcs/lambda.cs
  12. 20
      ICSharpCode.NRefactory/CSharp/Parser/mcs/method.cs
  13. 78
      ICSharpCode.NRefactory/CSharp/Parser/mcs/statement.cs
  14. 12
      ICSharpCode.NRefactory/CSharp/Parser/mcs/support.cs
  15. 38
      ICSharpCode.NRefactory/CSharp/Parser/mcs/typemanager.cs
  16. 48
      ICSharpCode.NRefactory/CSharp/Parser/mcs/typespec.cs

2
ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

@ -1081,7 +1081,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1081,7 +1081,7 @@ namespace ICSharpCode.NRefactory.CSharp
result.AddChild (init, VariableDeclarationStatement.Roles.Variable);
}
}
if (location != null && blockVariableDeclaration.Initializer == null || location.Count > 1)
if (location != null && (blockVariableDeclaration.Initializer == null || location.Count > 1))
result.AddChild (new CSharpTokenNode (Convert (location[location.Count - 1]), 1), VariableDeclarationStatement.Roles.Semicolon);
return result;
}

32
ICSharpCode.NRefactory/CSharp/Parser/mcs/anonymous.cs

@ -830,15 +830,20 @@ namespace Mono.CSharp { @@ -830,15 +830,20 @@ namespace Mono.CSharp {
}
}
Dictionary<TypeSpec, Expression> compatibles;
readonly Dictionary<TypeSpec, Expression> compatibles;
readonly bool is_async;
public ParametersBlock Block;
public AnonymousMethodExpression (Location loc)
public AnonymousMethodExpression (bool isAsync, Location loc)
{
this.is_async = isAsync;
this.loc = loc;
this.compatibles = new Dictionary<TypeSpec, Expression> ();
}
#region Properties
public override string ExprClassName {
get {
return "anonymous method";
@ -850,11 +855,15 @@ namespace Mono.CSharp { @@ -850,11 +855,15 @@ namespace Mono.CSharp {
return Parameters != ParametersCompiled.Undefined;
}
}
public ParametersCompiled Parameters {
get { return Block.Parameters; }
get {
return Block.Parameters;
}
}
#endregion
//
// Returns true if the body of lambda expression can be implicitly
// converted to the delegate of type `delegate_type'
@ -1079,6 +1088,10 @@ namespace Mono.CSharp { @@ -1079,6 +1088,10 @@ namespace Mono.CSharp {
am = CreateExpressionTree (ec, delegate_type);
}
} else {
if (is_async) {
AsyncInitializer.Create (body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent, body.ReturnType, loc);
}
am = body.Compatible (ec);
}
} catch (CompletionResult) {
@ -1204,7 +1217,6 @@ namespace Mono.CSharp { @@ -1204,7 +1217,6 @@ namespace Mono.CSharp {
ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block;
return CompatibleMethodFactory (return_type, delegate_type, p, b);
}
protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b)
@ -1421,7 +1433,15 @@ namespace Mono.CSharp { @@ -1421,7 +1433,15 @@ namespace Mono.CSharp {
}
public override bool IsIterator {
get { return false; }
get {
return false;
}
}
public ParametersCompiled Parameters {
get {
return parameters;
}
}
public TypeInferenceContext ReturnTypeInference {

313
ICSharpCode.NRefactory/CSharp/Parser/mcs/async.cs

@ -20,7 +20,77 @@ using System.Reflection.Emit; @@ -20,7 +20,77 @@ using System.Reflection.Emit;
namespace Mono.CSharp
{
class Await : YieldStatement<AsyncInitializer>
class Await : ExpressionStatement
{
readonly Expression expr;
AwaitStatement stmt;
public Await (Expression expr, Location loc)
{
this.expr = expr;
this.loc = loc;
}
public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotImplementedException ("ET");
}
protected override Expression DoResolve (ResolveContext rc)
{
if (rc.HasSet (ResolveContext.Options.FinallyScope)) {
rc.Report.Error (1984, loc,
"The `await' operator cannot be used in the body of a finally clause");
}
if (rc.HasSet (ResolveContext.Options.CatchScope)) {
rc.Report.Error (1985, loc,
"The `await' operator cannot be used in the body of a catch clause");
}
if (rc.HasSet (ResolveContext.Options.LockScope)) {
rc.Report.Error (1996, loc,
"The `await' operator cannot be used in the body of a lock statement");
}
if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) {
rc.Report.Error (1989, loc, "An expression tree cannot contain an await operator");
return null;
}
if (rc.IsUnsafe) {
// TODO: New error code
rc.Report.Error (-1900, loc,
"The `await' operator cannot be used in an unsafe context");
}
var bc = (BlockContext) rc;
if (!bc.CurrentBlock.ParametersBlock.IsAsync) {
// TODO: Should check for existence of await type but
// what to do with it
}
stmt = new AwaitStatement (expr, loc);
stmt.Resolve (bc);
type = stmt.ResultType;
eclass = ExprClass.Variable;
return this;
}
public override void Emit (EmitContext ec)
{
stmt.Emit (ec);
}
public override void EmitStatement (EmitContext ec)
{
stmt.EmitStatement (ec);
}
}
class AwaitStatement : YieldStatement<AsyncInitializer>
{
sealed class AwaitableMemberAccess : MemberAccess
{
@ -43,17 +113,30 @@ namespace Mono.CSharp @@ -43,17 +113,30 @@ namespace Mono.CSharp
Field awaiter;
PropertyExpr is_completed;
MethodSpec on_completed;
MethodSpec get_result;
TypeSpec type;
public Await (Expression expr, Location loc)
public AwaitStatement (Expression expr, Location loc)
: base (expr, loc)
{
}
public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotImplementedException ();
#region Properties
public TypeSpec Type {
get {
return type;
}
}
public TypeSpec ResultType {
get {
return get_result.ReturnType;
}
}
#endregion
protected override void DoEmit (EmitContext ec)
{
var fe_awaiter = new FieldExpr (awaiter, loc);
@ -83,6 +166,28 @@ namespace Mono.CSharp @@ -83,6 +166,28 @@ namespace Mono.CSharp
mg_completed.EmitCall (ec, args);
base.DoEmit (ec);
//
// result = awaiter.GetResult ();
//
var mg_result = MethodGroupExpr.CreatePredefined (get_result, fe_awaiter.Type, loc);
mg_result.InstanceExpression = fe_awaiter;
mg_result.EmitCall (ec, new Arguments (0));
}
public void EmitStatement (EmitContext ec)
{
Emit (ec);
if (ResultType.Kind != MemberKind.Void) {
var storey = (AsyncTaskStorey) machine_initializer.Storey;
if (storey.HoistedReturn != null)
storey.HoistedReturn.EmitAssign (ec);
else
ec.Emit (OpCodes.Pop);
}
}
static void Error_WrongGetAwaiter (ResolveContext rc, Location loc, TypeSpec type)
@ -103,8 +208,10 @@ namespace Mono.CSharp @@ -103,8 +208,10 @@ namespace Mono.CSharp
if (!base.Resolve (bc))
return false;
type = expr.Type;
//
// The task t is of type dynamic
// The task result is of dynamic type
//
if (expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
throw new NotImplementedException ("dynamic await");
@ -133,7 +240,7 @@ namespace Mono.CSharp @@ -133,7 +240,7 @@ namespace Mono.CSharp
expr = ama;
//
// bool IsCompleted { get; }
// Predefined: bool IsCompleted { get; }
//
var is_completed_ma = new MemberAccess (expr, "IsCompleted").Resolve (bc);
if (is_completed_ma != null) {
@ -155,7 +262,7 @@ namespace Mono.CSharp @@ -155,7 +262,7 @@ namespace Mono.CSharp
}
//
// void OnCompleted (Action)
// Predefined: OnCompleted (Action)
//
if (bc.Module.PredefinedTypes.Action.Define ()) {
on_completed = MemberCache.FindMember (awaiter_type, MemberFilter.Method ("OnCompleted", 0,
@ -168,6 +275,20 @@ namespace Mono.CSharp @@ -168,6 +275,20 @@ namespace Mono.CSharp
}
}
//
// Predefined: GetResult ()
//
// The method return type is also result type of await expression
//
get_result = MemberCache.FindMember (awaiter_type, MemberFilter.Method ("GetResult", 0,
ParametersCompiled.EmptyReadOnlyParameters, null),
BindingRestriction.InstanceOnly) as MethodSpec;
if (get_result == null) {
Error_WrongAwaiterPattern (bc, awaiter_type);
return false;
}
return true;
}
}
@ -191,9 +312,14 @@ namespace Mono.CSharp @@ -191,9 +312,14 @@ namespace Mono.CSharp
}
}
public static void Create (ParametersBlock block, TypeContainer host, TypeSpec returnType)
public static void Create (ParametersBlock block, ParametersCompiled parameters, TypeContainer host, TypeSpec returnType, Location loc)
{
ParametersCompiled parameters = block.Parameters;
if (returnType.Kind != MemberKind.Void &&
returnType != host.Module.PredefinedTypes.Task.TypeSpec &&
!returnType.IsGenericTask) {
host.Compiler.Report.Error (1983, loc, "The return type of an async method must be void, Task, or Task<T>");
}
for (int i = 0; i < parameters.Count; i++) {
Parameter p = parameters[i];
Parameter.Modifier mod = p.ModFlags;
@ -218,13 +344,16 @@ namespace Mono.CSharp @@ -218,13 +344,16 @@ namespace Mono.CSharp
}
}
// TODO:
//if ((modifiers & Modifiers.UNSAFE) != 0) {
// parent.Compiler.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators");
// TODO: Warning
//if (!block.HasAwait) {
//}
var init = block.WrapIntoAsyncTask (host, returnType);
init.type = host.Compiler.BuiltinTypes.Void;
block.WrapIntoAsyncTask (host, returnType);
}
public override Expression CreateExpressionTree (ResolveContext ec)
{
return base.CreateExpressionTree (ec);
}
public override void Emit (EmitContext ec)
@ -232,27 +361,69 @@ namespace Mono.CSharp @@ -232,27 +361,69 @@ namespace Mono.CSharp
throw new NotImplementedException ();
}
protected override void EmitMoveNextEpilogue (EmitContext ec)
{
base.EmitMoveNextEpilogue (ec);
var storey = (AsyncTaskStorey) Storey;
storey.EmitSetResult (ec);
}
public override void EmitStatement (EmitContext ec)
{
var storey = (AsyncTaskStorey) Storey;
storey.Instance.Emit (ec);
ec.Emit (OpCodes.Call, storey.StateMachineMethod.Spec);
if (storey.Task != null) {
//
// async.$builder.Task;
//
var pe_task = new PropertyExpr (storey.Task, loc) {
InstanceExpression = new FieldExpr (storey.Builder, loc) {
InstanceExpression = storey.Instance
},
Getter = storey.Task.Get
};
pe_task.Emit (ec);
}
ec.Emit (OpCodes.Ret);
}
public override void InjectYield (EmitContext ec, Expression expr, int resume_pc, bool unwind_protect, Label resume_point)
{
base.InjectYield (ec, expr, resume_pc, unwind_protect, resume_point);
}
}
class AsyncTaskStorey : StateMachine
{
int awaiters;
Field continuation;
Field builder, continuation;
readonly TypeSpec return_type;
MethodSpec set_result;
PropertySpec task;
LocalVariable hoisted_return;
public AsyncTaskStorey (AsyncInitializer initializer)
public AsyncTaskStorey (AsyncInitializer initializer, TypeSpec type)
: base (initializer.Block, initializer.Host, null, null, "async")
{
return_type = type;
}
public Field AddAwaiter (TypeSpec type, Location loc)
{
var field = AddCompilerGeneratedField ("$awaiter" + awaiters++.ToString ("X"), new TypeExpression (type, loc));
return field;
return AddCompilerGeneratedField ("$awaiter" + awaiters++.ToString ("X"), new TypeExpression (type, loc));
}
#region Properties
public Field Builder {
get {
return builder;
}
}
public Field Continuation {
@ -261,6 +432,26 @@ namespace Mono.CSharp @@ -261,6 +432,26 @@ namespace Mono.CSharp
}
}
public LocalVariable HoistedReturn {
get {
return hoisted_return;
}
}
public TypeSpec ReturnType {
get {
return return_type;
}
}
public PropertySpec Task {
get {
return task;
}
}
#endregion
protected override bool DoDefineMembers ()
{
var action = Module.PredefinedTypes.Action.Resolve ();
@ -269,18 +460,65 @@ namespace Mono.CSharp @@ -269,18 +460,65 @@ namespace Mono.CSharp
continuation.ModFlags |= Modifiers.READONLY;
}
PredefinedType builder_type;
PredefinedMember<MethodSpec> bf;
PredefinedMember<MethodSpec> sr;
bool has_task_return_type = false;
var pred_members = Module.PredefinedMembers;
if (return_type.Kind == MemberKind.Void) {
builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder;
bf = pred_members.AsyncVoidMethodBuilderCreate;
sr = pred_members.AsyncVoidMethodBuilderSetResult;
} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder;
bf = pred_members.AsyncTaskMethodBuilderCreate;
sr = pred_members.AsyncTaskMethodBuilderSetResult;
task = pred_members.AsyncTaskMethodBuilderTask.Resolve (Location);
} else {
builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric;
bf = pred_members.AsyncTaskMethodBuilderGenericCreate;
sr = pred_members.AsyncTaskMethodBuilderGenericSetResult;
task = pred_members.AsyncTaskMethodBuilderGenericTask.Resolve (Location);
has_task_return_type = true;
}
set_result = sr.Resolve (Location);
var builder_factory = bf.Resolve (Location);
var bt = builder_type.Resolve ();
if (bt == null || set_result == null || builder_factory == null)
return false;
//
// Inflate generic Task types
//
if (has_task_return_type) {
bt = bt.MakeGenericType (Module, return_type.TypeArguments);
builder_factory = MemberCache.GetMember<MethodSpec> (bt, builder_factory);
set_result = MemberCache.GetMember<MethodSpec> (bt, set_result);
if (task != null)
task = MemberCache.GetMember<PropertySpec> (bt, task);
}
builder = AddCompilerGeneratedField ("$builder", new TypeExpression (bt, Location));
builder.ModFlags |= Modifiers.READONLY;
if (!base.DoDefineMembers ())
return false;
MethodGroupExpr mg;
var block = instance_constructors[0].Block;
//
// Initialize continuation with state machine method
//
if (continuation != null) {
var args = new Arguments (1);
var mg = MethodGroupExpr.CreatePredefined (StateMachineMethod.Spec, spec, Location);
mg = MethodGroupExpr.CreatePredefined (StateMachineMethod.Spec, spec, Location);
args.Add (new Argument (mg));
instance_constructors[0].Block.AddStatement (
block.AddStatement (
new StatementExpression (new SimpleAssign (
new FieldExpr (continuation, Location),
new NewDelegate (action, args, Location),
@ -288,7 +526,40 @@ namespace Mono.CSharp @@ -288,7 +526,40 @@ namespace Mono.CSharp
)));
}
mg = MethodGroupExpr.CreatePredefined (builder_factory, bt, Location);
block.AddStatement (
new StatementExpression (new SimpleAssign (
new FieldExpr (builder, Location),
new Invocation (mg, new Arguments (0)),
Location)));
if (has_task_return_type) {
hoisted_return = LocalVariable.CreateCompilerGenerated (bt.TypeArguments[0], block, Location);
}
return true;
}
public void EmitSetResult (EmitContext ec)
{
//
// $builder.SetResult ();
// $builder.SetResult<return-type> (value);
//
var mg = MethodGroupExpr.CreatePredefined (set_result, set_result.DeclaringType, Location);
mg.InstanceExpression = new FieldExpr (Builder, Location) {
InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
};
Arguments args;
if (hoisted_return == null) {
args = new Arguments (0);
} else {
args = new Arguments (1);
args.Add (new Argument (new LocalVariableReference (hoisted_return, Location)));
}
mg.EmitCall (ec, args);
}
}
}

2
ICSharpCode.NRefactory/CSharp/Parser/mcs/context.cs

@ -267,6 +267,8 @@ namespace Mono.CSharp @@ -267,6 +267,8 @@ namespace Mono.CSharp
UsingInitializerScope = 1 << 12,
LockScope = 1 << 13,
/// <summary>
/// Whether control flow analysis is enabled
/// </summary>

9350
ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

94
ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-parser.jay

@ -1308,9 +1308,14 @@ method_header @@ -1308,9 +1308,14 @@ method_header
| opt_attributes
opt_modifiers
PARTIAL
VOID method_declaration_name
VOID
{
lexer.parsing_generic_declaration = true;
}
method_declaration_name
OPEN_PARENS
{
lexer.parsing_generic_declaration = false;
valid_param_mod = ParameterModifierType.All;
}
opt_formal_parameter_list CLOSE_PARENS
@ -1322,10 +1327,10 @@ method_header @@ -1322,10 +1327,10 @@ method_header
lexer.ConstraintsParsing = false;
valid_param_mod = 0;
MemberName name = (MemberName) $5;
current_local_parameters = (ParametersCompiled) $8;
MemberName name = (MemberName) $6;
current_local_parameters = (ParametersCompiled) $9;
if ($10 != null && name.TypeArguments == null)
if ($11 != null && name.TypeArguments == null)
report.Error (80, lexer.Location,
"Constraints are not allowed on non-generic declarations");
@ -1341,7 +1346,6 @@ method_header @@ -1341,7 +1346,6 @@ method_header
var modifiers = (Modifiers) $2;
const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN |
Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL;
@ -1364,9 +1368,8 @@ method_header @@ -1364,9 +1368,8 @@ method_header
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
// TODO: lbag, push void
StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($3));
lbag.AddMember (method, GetModifierLocations (), GetLocation ($6), GetLocation ($9));
lbag.AddMember (method, mod_locations, GetLocation ($7), GetLocation ($10));
$$ = method;
}
| opt_attributes
@ -3738,7 +3741,7 @@ pointer_member_access @@ -3738,7 +3741,7 @@ pointer_member_access
anonymous_method_expression
: DELEGATE opt_anonymous_method_signature
{
start_anonymous (false, (ParametersCompiled) $2, GetLocation ($1));
start_anonymous (false, (ParametersCompiled) $2, false, GetLocation ($1));
}
block
{
@ -3749,6 +3752,14 @@ anonymous_method_expression @@ -3749,6 +3752,14 @@ anonymous_method_expression
lbag.AddLocation ($$, GetLocation ($1));
}
}
| ASYNC DELEGATE opt_anonymous_method_signature
{
start_anonymous (false, (ParametersCompiled) $3, true, GetLocation ($1));
}
block
{
$$ = end_anonymous ((ParametersBlock) $5);
}
;
opt_anonymous_method_signature
@ -4144,32 +4155,54 @@ expression_or_error @@ -4144,32 +4155,54 @@ expression_or_error
lambda_expression
: IDENTIFIER ARROW
{
var lt = (Tokenizer.LocatedToken) $1;
var lt = (Tokenizer.LocatedToken) $1;
Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
start_anonymous (true, new ParametersCompiled (p), GetLocation ($1));
start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $4);
lbag.AddLocation ($$, GetLocation ($2));
}
| ASYNC IDENTIFIER ARROW
{
var lt = (Tokenizer.LocatedToken) $2;
Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
start_anonymous (true, new ParametersCompiled (p), true, lt.Location);
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $5);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
}
| OPEN_PARENS_LAMBDA
{
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "lambda expressions");
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_lambda_parameter_list CLOSE_PARENS ARROW
{
valid_param_mod = 0;
start_anonymous (true, (ParametersCompiled) $3, GetLocation ($1));
start_anonymous (true, (ParametersCompiled) $3, false, GetLocation ($1));
}
lambda_expression_body
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $7);
lbag.AddLocation ($$, GetLocation ($4), GetLocation ($5));
}
| ASYNC OPEN_PARENS_LAMBDA
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_lambda_parameter_list CLOSE_PARENS ARROW
{
valid_param_mod = 0;
start_anonymous (true, (ParametersCompiled) $4, true, GetLocation ($1));
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $8);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($5), GetLocation ($6));
}
;
expression
@ -4381,7 +4414,7 @@ modifier @@ -4381,7 +4414,7 @@ modifier
StoreModifierLocation ($$, GetLocation ($1));
}
;
opt_class_base
: /* empty */
| COLON type_list
@ -4939,12 +4972,8 @@ statement_expression @@ -4939,12 +4972,8 @@ statement_expression
{
ExpressionStatement s = $1 as ExpressionStatement;
if (s == null) {
if ($1 is Statement) {
$$ = $1;
} else {
Expression.Error_InvalidExpressionStatement (report, GetLocation ($1));
$$ = new StatementExpression (EmptyExpressionStatement.Instance);
}
Expression.Error_InvalidExpressionStatement (report, GetLocation ($1));
$$ = new StatementExpression (EmptyExpressionStatement.Instance);
} else {
$$ = new StatementExpression (s);
}
@ -6511,21 +6540,24 @@ end_block (Location loc) @@ -6511,21 +6540,24 @@ end_block (Location loc)
return retval;
}
void start_anonymous (bool lambda, ParametersCompiled parameters, Location loc)
void start_anonymous (bool isLambda, ParametersCompiled parameters, bool isAsync, Location loc)
{
if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (loc, "anonymous methods");
}
oob_stack.Push (current_anonymous_method);
oob_stack.Push (current_local_parameters);
oob_stack.Push (current_variable);
current_local_parameters = parameters;
if (isLambda) {
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (loc, "lambda expressions");
current_anonymous_method = lambda
? new LambdaExpression (loc)
: new AnonymousMethodExpression (loc);
current_anonymous_method = new LambdaExpression (isAsync, loc);
} else {
if (lang_version == LanguageVersion.ISO_1)
FeatureIsNotAvailable (loc, "anonymous methods");
current_anonymous_method = new AnonymousMethodExpression (isAsync, loc);
}
// Force the next block to be created as a ToplevelBlock
parsing_anonymous_method = true;
@ -6556,6 +6588,8 @@ void Error_SyntaxError (int token) @@ -6556,6 +6588,8 @@ void Error_SyntaxError (int token)
void Error_SyntaxError (int error_code, int token, string msg)
{
Lexer.CompleteOnEOF = false;
// An error message has been reported by tokenizer
if (token == Token.ERROR)
return;

75
ICSharpCode.NRefactory/CSharp/Parser/mcs/cs-tokenizer.cs

@ -789,7 +789,7 @@ namespace Mono.CSharp @@ -789,7 +789,7 @@ namespace Mono.CSharp
// TODO: async, it's modifiers context only
case Token.ASYNC:
if (parsing_block > 0 || context.Settings.Version != LanguageVersion.Future) {
if (context.Settings.Version != LanguageVersion.Future) {
res = -1;
}
break;
@ -1080,6 +1080,8 @@ namespace Mono.CSharp @@ -1080,6 +1080,8 @@ namespace Mono.CSharp
case Token.VOID:
break;
case Token.OP_GENERICS_GT:
case Token.IN:
case Token.OUT:
return true;
default:
@ -1376,9 +1378,8 @@ namespace Mono.CSharp @@ -1376,9 +1378,8 @@ namespace Mono.CSharp
// we need to convert to a special type, and then choose
// the best representation for the integer
//
int adjust_int (int c, Location loc)
ILiteralConstant adjust_int (int c, Location loc)
{
ILiteralConstant res;
try {
if (number_pos > 9){
ulong ul = (uint) (number_builder [0] - '0');
@ -1386,30 +1387,25 @@ namespace Mono.CSharp @@ -1386,30 +1387,25 @@ namespace Mono.CSharp
for (int i = 1; i < number_pos; i++){
ul = checked ((ul * 10) + ((uint)(number_builder [i] - '0')));
}
res = integer_type_suffix (ul, c, loc);
return integer_type_suffix (ul, c, loc);
} else {
uint ui = (uint) (number_builder [0] - '0');
for (int i = 1; i < number_pos; i++){
ui = checked ((ui * 10) + ((uint)(number_builder [i] - '0')));
}
res = integer_type_suffix (ui, c, loc);
return integer_type_suffix (ui, c, loc);
}
} catch (OverflowException) {
Error_NumericConstantTooLong ();
res = new IntLiteral (context.BuiltinTypes, 0, loc);
return new IntLiteral (context.BuiltinTypes, 0, loc);
}
catch (FormatException) {
Report.Error (1013, Location, "Invalid number");
res = new IntLiteral (context.BuiltinTypes, 0, loc);
return new IntLiteral (context.BuiltinTypes, 0, loc);
}
val = res;
#if FULL_AST
res.ParsedValue = new char[number_pos];
Array.Copy (number_builder, res.ParsedValue, number_pos);
#endif
return Token.LITERAL;
}
ILiteralConstant adjust_real (TypeCode t, Location loc)
@ -1482,6 +1478,9 @@ namespace Mono.CSharp @@ -1482,6 +1478,9 @@ namespace Mono.CSharp
{
ILiteralConstant res;
#if FULL_AST
int read_start = reader.Position - 1;
#endif
number_pos = 0;
var loc = Location;
@ -1490,13 +1489,9 @@ namespace Mono.CSharp @@ -1490,13 +1489,9 @@ namespace Mono.CSharp
int peek = peek_char ();
if (peek == 'x' || peek == 'X') {
res = handle_hex (loc);
val = res;
val = res = handle_hex (loc);
#if FULL_AST
res.ParsedValue = new char[number_pos + 2];
res.ParsedValue[0] = (char) c;
res.ParsedValue[1] = (char) peek;
Array.Copy (number_builder, 0, res.ParsedValue, 2, number_pos);
res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1);
#endif
return Token.LITERAL;
@ -1518,7 +1513,12 @@ namespace Mono.CSharp @@ -1518,7 +1513,12 @@ namespace Mono.CSharp
} else {
putback ('.');
number_pos--;
return adjust_int (-1, loc);
val = res = adjust_int (-1, loc);
#if FULL_AST
res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1);
#endif
return Token.LITERAL;
}
}
@ -1550,25 +1550,23 @@ namespace Mono.CSharp @@ -1550,25 +1550,23 @@ namespace Mono.CSharp
}
var type = real_type_suffix (c);
if (type == TypeCode.Empty && !is_real){
if (type == TypeCode.Empty && !is_real) {
putback (c);
return adjust_int (c, loc);
}
res = adjust_int (c, loc);
} else {
is_real = true;
is_real = true;
if (type == TypeCode.Empty) {
putback (c);
}
if (type == TypeCode.Empty){
putback (c);
c = 0;
res = adjust_real (type, loc);
}
val = res = adjust_real (type, loc);
val = res;
#if FULL_AST
res.ParsedValue = new char[number_pos + (c != 0 ? 1 : 0)];
Array.Copy (number_builder, res.ParsedValue, number_pos);
if (c != 0)
res.ParsedValue[number_pos] = (char) c;
res.ParsedValue = reader.ReadChars (read_start, reader.Position - (type == TypeCode.Empty ? 1 : 0));
#endif
return Token.LITERAL;
@ -2699,6 +2697,10 @@ namespace Mono.CSharp @@ -2699,6 +2697,10 @@ namespace Mono.CSharp
if (quoted)
start_location = start_location - 1;
#if FULL_AST
int reader_pos = reader.Position;
#endif
while (true){
c = get_char ();
if (c == '"') {
@ -2719,7 +2721,12 @@ namespace Mono.CSharp @@ -2719,7 +2721,12 @@ namespace Mono.CSharp
else
s = new string (value_builder, 0, pos);
val = new StringLiteral (context.BuiltinTypes, s, start_location);
ILiteralConstant res = new StringLiteral (context.BuiltinTypes, s, start_location);
val = res;
#if FULL_AST
res.ParsedValue = reader.ReadChars (reader_pos - (quoted ? 2 : 1), reader.Position);
#endif
return Token.LITERAL;
}

1
ICSharpCode.NRefactory/CSharp/Parser/mcs/decl.cs

@ -923,6 +923,7 @@ namespace Mono.CSharp { @@ -923,6 +923,7 @@ namespace Mono.CSharp {
InflatedExpressionType = 1 << 19,
InflatedNullableType = 1 << 20,
GenericIterateInterface = 1 << 21,
GenericTask = 1 << 22
}
protected Modifiers modifiers;

6
ICSharpCode.NRefactory/CSharp/Parser/mcs/generic.cs

@ -1517,6 +1517,12 @@ namespace Mono.CSharp { @@ -1517,6 +1517,12 @@ namespace Mono.CSharp {
}
}
public override bool IsGenericTask {
get {
return (open_type.state & StateFlags.GenericTask) != 0;
}
}
public override bool IsNullableType {
get {
return (open_type.state & StateFlags.InflatedNullableType) != 0;

36
ICSharpCode.NRefactory/CSharp/Parser/mcs/iterators.cs

@ -649,13 +649,21 @@ namespace Mono.CSharp @@ -649,13 +649,21 @@ namespace Mono.CSharp
protected override Expression DoResolve (ResolveContext ec)
{
storey = (StateMachine) block.TopBlock.AnonymousMethodStorey;
storey = (StateMachine) block.Parent.ParametersBlock.AnonymousMethodStorey;
BlockContext ctx = new BlockContext (ec, block, ReturnType);
ctx.CurrentAnonymousMethod = this;
ctx.StartFlowBranching (this, ec.CurrentBranching);
Block.Resolve (ctx);
//
// Explicit return is required for Task<T> state machine
//
var task_storey = storey as AsyncTaskStorey;
if (task_storey == null || !task_storey.ReturnType.IsGenericTask)
ctx.CurrentBranching.CurrentUsageVector.Goto ();
ctx.EndFlowBranching ();
var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc));
@ -740,9 +748,10 @@ namespace Mono.CSharp @@ -740,9 +748,10 @@ namespace Mono.CSharp
ec.MarkLabel (move_next_error);
if (ReturnType.Kind != MemberKind.Void)
if (ReturnType.Kind != MemberKind.Void) {
ec.EmitInt (0);
ec.Emit (OpCodes.Ret);
ec.Emit (OpCodes.Ret);
}
}
void EmitMoveNext (EmitContext ec)
@ -796,25 +805,32 @@ namespace Mono.CSharp @@ -796,25 +805,32 @@ namespace Mono.CSharp
SymbolWriter.StartIteratorDispatcher (ec);
ec.Emit (OpCodes.Ldarg_0);
ec.EmitInt ((int) IteratorStorey.State.After);
ec.Emit (OpCodes.Stfld, storey.PC.Spec);
EmitMoveNextEpilogue (ec);
ec.MarkLabel (move_next_error);
if (ReturnType.Kind != MemberKind.Void)
if (ReturnType.Kind != MemberKind.Void) {
ec.EmitInt (0);
ec.Emit (OpCodes.Ret);
ec.Emit (OpCodes.Ret);
}
ec.MarkLabel (move_next_ok);
if (ReturnType.Kind != MemberKind.Void)
if (ReturnType.Kind != MemberKind.Void) {
ec.EmitInt (1);
ec.Emit (OpCodes.Ret);
ec.Emit (OpCodes.Ret);
}
SymbolWriter.EndIteratorDispatcher (ec);
}
protected virtual void EmitMoveNextEpilogue (EmitContext ec)
{
ec.Emit (OpCodes.Ldarg_0);
ec.EmitInt ((int) IteratorStorey.State.After);
ec.Emit (OpCodes.Stfld, storey.PC.Spec);
}
//
// Called back from YieldStatement
//

7
ICSharpCode.NRefactory/CSharp/Parser/mcs/lambda.cs

@ -23,8 +23,13 @@ namespace Mono.CSharp { @@ -23,8 +23,13 @@ namespace Mono.CSharp {
// A list of Parameters (explicitly typed parameters)
// An ImplicitLambdaParameter
//
public LambdaExpression (bool isAsync, Location loc)
: base (isAsync, loc)
{
}
public LambdaExpression (Location loc)
: base (loc)
: this (false, loc)
{
}

20
ICSharpCode.NRefactory/CSharp/Parser/mcs/method.cs

@ -597,6 +597,13 @@ namespace Mono.CSharp { @@ -597,6 +597,13 @@ namespace Mono.CSharp {
// MethodBase mb = new PartialMethodDefinitionInfo (this);
spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
if (MemberName.Arity > 0) {
spec.IsGeneric = true;
// TODO: Have to move DefineMethod after Define (ideally to Emit)
throw new NotImplementedException ("Generic partial methods");
}
Parent.MemberCache.AddMember (spec);
}
@ -1083,7 +1090,7 @@ namespace Mono.CSharp { @@ -1083,7 +1090,7 @@ namespace Mono.CSharp {
continue;
}
if (MethodData.implementing != null) {
if (MethodData != null && MethodData.implementing != null) {
var base_tp = MethodData.implementing.Constraints[i];
if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
Report.SymbolRelatedToPreviousError (MethodData.implementing);
@ -1144,16 +1151,7 @@ namespace Mono.CSharp { @@ -1144,16 +1151,7 @@ namespace Mono.CSharp {
}
if ((ModFlags & Modifiers.ASYNC) != 0) {
if (ReturnType.Kind != MemberKind.Void && ReturnType != Module.PredefinedTypes.Task.TypeSpec && ReturnType != Module.PredefinedTypes.TaskGeneric.TypeSpec) {
Report.Error (1983, type_expr.Location, "The return type of an async method `{0}' must be void, Task, or Task<T>",
GetSignatureForError ());
}
if (!block.IsAsync) {
// TODO: Warning
}
AsyncInitializer.Create (block, Parent.PartialContainer, ReturnType);
AsyncInitializer.Create (block, parameters, Parent.PartialContainer, ReturnType, Location);
}
}

78
ICSharpCode.NRefactory/CSharp/Parser/mcs/statement.cs

@ -624,7 +624,8 @@ namespace Mono.CSharp { @@ -624,7 +624,8 @@ namespace Mono.CSharp {
}
}
public class StatementExpression : Statement {
public class StatementExpression : Statement
{
ExpressionStatement expr;
public StatementExpression (ExpressionStatement expr)
@ -637,10 +638,10 @@ namespace Mono.CSharp { @@ -637,10 +638,10 @@ namespace Mono.CSharp {
get { return this.expr; }
}
public override bool Resolve (BlockContext ec)
protected override void CloneTo (CloneContext clonectx, Statement t)
{
expr = expr.ResolveStatement (ec);
return expr != null;
StatementExpression target = (StatementExpression) t;
target.expr = (ExpressionStatement) expr.Clone (clonectx);
}
protected override void DoEmit (EmitContext ec)
@ -648,16 +649,10 @@ namespace Mono.CSharp { @@ -648,16 +649,10 @@ namespace Mono.CSharp {
expr.EmitStatement (ec);
}
public override string ToString ()
{
return "StatementExpression (" + expr + ")";
}
protected override void CloneTo (CloneContext clonectx, Statement t)
public override bool Resolve (BlockContext ec)
{
StatementExpression target = (StatementExpression) t;
target.expr = (ExpressionStatement) expr.Clone (clonectx);
expr = expr.ResolveStatement (ec);
return expr != null;
}
public override object Accept (StructuralVisitor visitor)
@ -750,7 +745,7 @@ namespace Mono.CSharp { @@ -750,7 +745,7 @@ namespace Mono.CSharp {
public class Return : ExitStatement
{
public Expression Expr { get; protected set; }
public Return (Expression expr, Location l)
{
Expr = expr;
@ -783,10 +778,11 @@ namespace Mono.CSharp { @@ -783,10 +778,11 @@ namespace Mono.CSharp {
}
Expr = Expr.Resolve (ec);
TypeSpec block_return_type = ec.ReturnType;
AnonymousExpression am = ec.CurrentAnonymousMethod;
if (am == null) {
if (ec.ReturnType.Kind == MemberKind.Void) {
if (block_return_type.Kind == MemberKind.Void) {
ec.Report.Error (127, loc,
"`{0}': A return keyword must not be followed by any expression when method returns void",
ec.GetSignatureForError ());
@ -798,9 +794,22 @@ namespace Mono.CSharp { @@ -798,9 +794,22 @@ namespace Mono.CSharp {
}
if (am is AsyncInitializer) {
ec.Report.Error (1997, loc,
"`{0}': A return keyword must not be followed by an expression when method is async",
ec.GetSignatureForError ());
if (Expr != null) {
var storey = (AsyncTaskStorey) am.Storey;
var async_type = storey.ReturnType;
if (!async_type.IsGenericTask) {
ec.Report.Error (1997, loc,
"`{0}': A return keyword must not be followed by an expression when async method returns Task. Consider using Task<T>",
ec.GetSignatureForError ());
return false;
}
//
// The return type is actually Task<T> type argument
//
block_return_type = async_type.TypeArguments[0];
}
} else {
var l = am as AnonymousMethodBody;
if (l != null && l.ReturnTypeInference != null && Expr != null) {
@ -813,11 +822,11 @@ namespace Mono.CSharp { @@ -813,11 +822,11 @@ namespace Mono.CSharp {
if (Expr == null)
return false;
if (Expr.Type != ec.ReturnType) {
Expr = Convert.ImplicitConversionRequired (ec, Expr, ec.ReturnType, loc);
if (Expr.Type != block_return_type) {
Expr = Convert.ImplicitConversionRequired (ec, Expr, block_return_type, loc);
if (Expr == null) {
if (am != null) {
if (am != null && block_return_type == ec.ReturnType) {
ec.Report.Error (1662, loc,
"Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
am.ContainerType, am.GetSignatureForError ());
@ -834,6 +843,12 @@ namespace Mono.CSharp { @@ -834,6 +843,12 @@ namespace Mono.CSharp {
if (Expr != null) {
Expr.Emit (ec);
var async_body = ec.CurrentAnonymousMethod as AsyncInitializer;
if (async_body != null) {
((AsyncTaskStorey) async_body.Storey).HoistedReturn.EmitAssign (ec);
return;
}
if (unwind_protect)
ec.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
}
@ -2725,18 +2740,20 @@ namespace Mono.CSharp { @@ -2725,18 +2740,20 @@ namespace Mono.CSharp {
AddStatement (new Return (iterator, iterator.Location));
}
public AsyncInitializer WrapIntoAsyncTask (TypeContainer host, TypeSpec returnType)
public void WrapIntoAsyncTask (TypeContainer host, TypeSpec returnType)
{
ParametersBlock pb = new ParametersBlock (this, ParametersCompiled.EmptyReadOnlyParameters, StartLocation);
pb.EndLocation = EndLocation;
pb.statements = statements;
var initializer = new AsyncInitializer (pb, host, returnType);
am_storey = new AsyncTaskStorey (initializer);
var block_type = host.Module.Compiler.BuiltinTypes.Void;
var initializer = new AsyncInitializer (pb, host, block_type);
initializer.Type = block_type;
am_storey = new AsyncTaskStorey (initializer, returnType);
statements = new List<Statement> (1);
AddStatement (new StatementExpression (initializer));
return initializer;
}
}
@ -4178,7 +4195,8 @@ namespace Mono.CSharp { @@ -4178,7 +4195,8 @@ namespace Mono.CSharp {
}
}
public class Lock : ExceptionStatement {
public class Lock : ExceptionStatement
{
Expression expr;
TemporaryVariableReference expr_copy;
TemporaryVariableReference lock_taken;
@ -4219,9 +4237,11 @@ namespace Mono.CSharp { @@ -4219,9 +4237,11 @@ namespace Mono.CSharp {
locked = false;
}
ec.StartFlowBranching (this);
Statement.Resolve (ec);
ec.EndFlowBranching ();
using (ec.Set (ResolveContext.Options.LockScope)) {
ec.StartFlowBranching (this);
Statement.Resolve (ec);
ec.EndFlowBranching ();
}
if (lv != null) {
lv.IsLockedByStatement = locked;

12
ICSharpCode.NRefactory/CSharp/Parser/mcs/support.cs

@ -237,6 +237,18 @@ namespace Mono.CSharp { @@ -237,6 +237,18 @@ namespace Mono.CSharp {
return pos < char_count;
}
public char[] ReadChars (int fromPosition, int toPosition)
{
char[] chars = new char[toPosition - fromPosition];
if (buffer_start <= fromPosition && toPosition < buffer_start + buffer.Length) {
Array.Copy (buffer, fromPosition, chars, 0, chars.Length);
} else {
throw new NotImplementedException ();
}
return chars;
}
public int Peek ()
{
if ((pos >= char_count) && !ReadBuffer ())

38
ICSharpCode.NRefactory/CSharp/Parser/mcs/typemanager.cs

@ -221,6 +221,8 @@ namespace Mono.CSharp @@ -221,6 +221,8 @@ namespace Mono.CSharp
// C# 5.0
//
public readonly PredefinedType AsyncVoidMethodBuilder;
public readonly PredefinedType AsyncTaskMethodBuilder;
public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
public readonly PredefinedType Action;
public readonly PredefinedType Task;
public readonly PredefinedType TaskGeneric;
@ -267,6 +269,8 @@ namespace Mono.CSharp @@ -267,6 +269,8 @@ namespace Mono.CSharp
Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
@ -296,13 +300,20 @@ namespace Mono.CSharp @@ -296,13 +300,20 @@ namespace Mono.CSharp
ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
Task.Define ();
TaskGeneric.Define ();
if (TaskGeneric.Define ())
TaskGeneric.TypeSpec.IsGenericTask = true;
}
}
class PredefinedMembers
{
public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
@ -349,6 +360,31 @@ namespace Mono.CSharp @@ -349,6 +360,31 @@ namespace Mono.CSharp
ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Property ("Task", null));
AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("SetResult", 0,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.NONE)
},
new[] {
new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null)
}, false), btypes.Void));
AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Property ("Task", null));
AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));

48
ICSharpCode.NRefactory/CSharp/Parser/mcs/typespec.cs

@ -197,6 +197,18 @@ namespace Mono.CSharp @@ -197,6 +197,18 @@ namespace Mono.CSharp
}
}
//
// Returns true for instances of System.Threading.Tasks.Task<T>
//
public virtual bool IsGenericTask {
get {
return false;
}
set {
state = value ? state | StateFlags.GenericTask : state & ~StateFlags.GenericTask;
}
}
// TODO: Should probably do
// IsGenericType -- recursive
// HasTypeParameter -- non-recursive
@ -1638,29 +1650,27 @@ namespace Mono.CSharp @@ -1638,29 +1650,27 @@ namespace Mono.CSharp
public override string GetSignatureForDocumentation ()
{
var e = Element;
List<int> ranks = new List<int> (2);
ranks.Add (rank);
StringBuilder sb = new StringBuilder ();
GetElementSignatureForDocumentation (sb);
return sb.ToString ();
}
while (e is ArrayContainer) {
var ac = (ArrayContainer) e;
ranks.Add (ac.rank);
e = ac.Element;
}
void GetElementSignatureForDocumentation (StringBuilder sb)
{
var ac = Element as ArrayContainer;
if (ac == null)
sb.Append (Element.GetSignatureForDocumentation ());
else
ac.GetElementSignatureForDocumentation (sb);
StringBuilder sb = new StringBuilder (e.GetSignatureForDocumentation ());
for (int r = 0; r < ranks.Count; ++r) {
sb.Append ("[");
for (int i = 1; i < ranks[r]; i++) {
if (i == 1)
sb.Append ("0:");
sb.Append ("[");
for (int i = 1; i < rank; i++) {
if (i == 1)
sb.Append ("0:");
sb.Append (",0:");
}
sb.Append ("]");
sb.Append (",0:");
}
return sb.ToString ();
sb.Append ("]");
}
public static ArrayContainer MakeType (ModuleContainer module, TypeSpec element)

Loading…
Cancel
Save