Browse Source

Updated mcs.

pull/32/merge
Mike Krüger 13 years ago
parent
commit
f9bc384c79
  1. 8
      ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
  2. 15
      ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
  3. 4
      ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs
  4. 8
      ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
  5. 24
      ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
  6. 35
      ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs
  7. 61
      ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
  8. 45
      ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
  9. 50
      ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs
  10. 8924
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  11. 62
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  12. 32
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  13. 29
      ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs
  14. 40
      ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs
  15. 9
      ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs
  16. 47
      ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  17. 30
      ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs
  18. 41
      ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs
  19. 4
      ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs
  20. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs
  21. 28
      ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  22. 13
      ICSharpCode.NRefactory.CSharp/Parser/mcs/typemanager.cs
  23. 12
      ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs

8
ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs

@ -130,24 +130,24 @@ namespace Mono.CompilerServices.SymbolWriter
public int NumLineNumbers; public int NumLineNumbers;
internal MonoSymbolFile () public MonoSymbolFile ()
{ {
ot = new OffsetTable (); ot = new OffsetTable ();
} }
internal int AddSource (SourceFileEntry source) public int AddSource (SourceFileEntry source)
{ {
sources.Add (source); sources.Add (source);
return sources.Count; return sources.Count;
} }
internal int AddCompileUnit (CompileUnitEntry entry) public int AddCompileUnit (CompileUnitEntry entry)
{ {
comp_units.Add (entry); comp_units.Add (entry);
return comp_units.Count; return comp_units.Count;
} }
internal void AddMethod (MethodEntry entry) public void AddMethod (MethodEntry entry)
{ {
methods.Add (entry); methods.Add (entry);
} }

15
ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs

@ -601,6 +601,11 @@ namespace Mono.CompilerServices.SymbolWriter
DataOffset = reader.ReadInt32 (); DataOffset = reader.ReadInt32 ();
} }
public void ReadAll ()
{
ReadData ();
}
void ReadData () void ReadData ()
{ {
if (creating) if (creating)
@ -746,6 +751,7 @@ namespace Mono.CompilerServices.SymbolWriter
public string FileName { public string FileName {
get { return file_name; } get { return file_name; }
set { file_name = value; }
} }
public bool AutoGenerated { public bool AutoGenerated {
@ -1208,6 +1214,15 @@ namespace Mono.CompilerServices.SymbolWriter
bw.WriteLeb128 ((int) flags); bw.WriteLeb128 ((int) flags);
} }
public void ReadAll ()
{
GetLineNumberTable ();
GetLocals ();
GetCodeBlocks ();
GetScopeVariables ();
GetRealName ();
}
public LineNumberTable GetLineNumberTable () public LineNumberTable GetLineNumberTable ()
{ {
lock (SymbolFile) { lock (SymbolFile) {

4
ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs

@ -47,11 +47,7 @@ namespace Mono.CompilerServices.SymbolWriter
string filename; string filename;
private SourceMethodBuilder current_method; private SourceMethodBuilder current_method;
#if NET_2_1
System.Collections.Stack current_method_stack = new System.Collections.Stack ();
#else
Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> (); Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> ();
#endif
public MonoSymbolWriter (string filename) public MonoSymbolWriter (string filename)
{ {

8
ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs

@ -37,11 +37,7 @@ namespace Mono.CompilerServices.SymbolWriter
List<LocalVariableEntry> _locals; List<LocalVariableEntry> _locals;
List<CodeBlockEntry> _blocks; List<CodeBlockEntry> _blocks;
List<ScopeVariable> _scope_vars; List<ScopeVariable> _scope_vars;
#if NET_2_1
System.Collections.Stack _block_stack;
#else
Stack<CodeBlockEntry> _block_stack; Stack<CodeBlockEntry> _block_stack;
#endif
readonly List<LineNumberEntry> method_lines; readonly List<LineNumberEntry> method_lines;
readonly ICompileUnit _comp_unit; readonly ICompileUnit _comp_unit;
@ -90,11 +86,7 @@ namespace Mono.CompilerServices.SymbolWriter
public void StartBlock (CodeBlockEntry.Type type, int start_offset) public void StartBlock (CodeBlockEntry.Type type, int start_offset)
{ {
if (_block_stack == null) { if (_block_stack == null) {
#if NET_2_1
_block_stack = new System.Collections.Stack ();
#else
_block_stack = new Stack<CodeBlockEntry> (); _block_stack = new Stack<CodeBlockEntry> ();
#endif
} }
if (_blocks == null) if (_blocks == null)

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

@ -1368,7 +1368,7 @@ namespace Mono.CSharp {
b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc); b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc);
} }
return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b); return CompatibleMethodFactory (return_type ?? InternalType.ErrorType, delegate_type, p, b);
} }
protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b) protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b)
@ -1635,21 +1635,25 @@ namespace Mono.CSharp {
parent = storey = FindBestMethodStorey (); parent = storey = FindBestMethodStorey ();
if (storey == null) { if (storey == null) {
var sm = src_block.ParametersBlock.TopBlock.StateMachine; var top_block = src_block.ParametersBlock.TopBlock;
var sm = top_block.StateMachine;
// if (src_block.HasCapturedThis) {
// Remove hoisted this demand when simple instance method is enough (no hoisted variables only this) //
// // Remove hoisted 'this' request when simple instance method is
if (src_block.HasCapturedThis && src_block.ParametersBlock.StateMachine == null) { // enough (no hoisted variables only 'this')
src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block); //
if (src_block.ParametersBlock.StateMachine == null)
top_block.RemoveThisReferenceFromChildrenBlock (src_block);
// //
// Special case where parent class is used to emit instance method // Special case where parent class is used to emit instance method
// because currect storey is of value type (async host) and we don't // because currect storey is of value type (async host). We cannot
// want to create another childer storey to host this reference only // use ldftn on non-boxed instances either to share mutated state
// //
if (sm != null && sm.Kind == MemberKind.Struct) if (sm != null && sm.Kind == MemberKind.Struct) {
parent = sm.Parent.PartialContainer; parent = sm.Parent.PartialContainer;
}
} }
// //

35
ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs

@ -154,6 +154,8 @@ namespace Mono.CSharp
} }
} }
public bool IsSatelliteAssembly { get; private set; }
public string Name { public string Name {
get { get {
return name; return name;
@ -214,6 +216,7 @@ namespace Mono.CSharp
builder_extra.SetCulture (value, a.Location); builder_extra.SetCulture (value, a.Location);
} }
IsSatelliteAssembly = true;
return; return;
} }
@ -457,26 +460,28 @@ namespace Mono.CSharp
} }
} }
if (!wrap_non_exception_throws_custom) { if (!IsSatelliteAssembly) {
PredefinedAttribute pa = module.PredefinedAttributes.RuntimeCompatibility; if (!wrap_non_exception_throws_custom) {
if (pa.IsDefined && pa.ResolveBuilder ()) { PredefinedAttribute pa = module.PredefinedAttributes.RuntimeCompatibility;
var prop = module.PredefinedMembers.RuntimeCompatibilityWrapNonExceptionThrows.Get (); if (pa.IsDefined && pa.ResolveBuilder ()) {
if (prop != null) { var prop = module.PredefinedMembers.RuntimeCompatibilityWrapNonExceptionThrows.Get ();
AttributeEncoder encoder = new AttributeEncoder (); if (prop != null) {
encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null)); AttributeEncoder encoder = new AttributeEncoder ();
SetCustomAttribute (pa.Constructor, encoder.ToArray ()); encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null));
SetCustomAttribute (pa.Constructor, encoder.ToArray ());
}
} }
} }
}
if (declarative_security != null) { if (declarative_security != null) {
#if STATIC #if STATIC
foreach (var entry in declarative_security) { foreach (var entry in declarative_security) {
Builder.__AddDeclarativeSecurity (entry); Builder.__AddDeclarativeSecurity (entry);
} }
#else #else
throw new NotSupportedException ("Assembly-level security"); throw new NotSupportedException ("Assembly-level security");
#endif #endif
}
} }
CheckReferencesPublicToken (); CheckReferencesPublicToken ();
@ -1104,8 +1109,8 @@ namespace Mono.CSharp
this.compiler = compiler; this.compiler = compiler;
paths = new List<string> (); paths = new List<string> ();
paths.AddRange (compiler.Settings.ReferencesLookupPaths);
paths.Add (Directory.GetCurrentDirectory ()); paths.Add (Directory.GetCurrentDirectory ());
paths.AddRange (compiler.Settings.ReferencesLookupPaths);
} }
public abstract bool HasObjectType (T assembly); public abstract bool HasObjectType (T assembly);

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

@ -129,13 +129,15 @@ namespace Mono.CSharp
public class AwaitStatement : YieldStatement<AsyncInitializer> public class AwaitStatement : YieldStatement<AsyncInitializer>
{ {
sealed class AwaitableMemberAccess : MemberAccess public sealed class AwaitableMemberAccess : MemberAccess
{ {
public AwaitableMemberAccess (Expression expr) public AwaitableMemberAccess (Expression expr)
: base (expr, "GetAwaiter") : base (expr, "GetAwaiter")
{ {
} }
public bool ProbingMode { get; set; }
protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name) protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name)
{ {
Error_OperatorCannotBeApplied (rc, type); Error_OperatorCannotBeApplied (rc, type);
@ -143,6 +145,9 @@ namespace Mono.CSharp
protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type) protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
{ {
if (ProbingMode)
return;
var invocation = LeftExpression as Invocation; var invocation = LeftExpression as Invocation;
if (invocation != null && invocation.MethodGroup != null && (invocation.MethodGroup.BestCandidate.Modifiers & Modifiers.ASYNC) != 0) { if (invocation != null && invocation.MethodGroup != null && (invocation.MethodGroup.BestCandidate.Modifiers & Modifiers.ASYNC) != 0) {
rc.Report.Error (4008, loc, "Cannot await void method `{0}'. Consider changing method return type to `Task'", rc.Report.Error (4008, loc, "Cannot await void method `{0}'. Consider changing method return type to `Task'",
@ -169,8 +174,7 @@ namespace Mono.CSharp
} }
Field awaiter; Field awaiter;
PropertySpec is_completed; AwaiterDefinition awaiter_definition;
MethodSpec get_result;
TypeSpec type; TypeSpec type;
TypeSpec result_type; TypeSpec result_type;
@ -183,7 +187,7 @@ namespace Mono.CSharp
bool IsDynamic { bool IsDynamic {
get { get {
return is_completed == null; return awaiter_definition == null;
} }
} }
@ -211,12 +215,12 @@ namespace Mono.CSharp
if (IsDynamic) { if (IsDynamic) {
var rc = new ResolveContext (ec.MemberContext); var rc = new ResolveContext (ec.MemberContext);
return new Invocation (new MemberAccess (fe_awaiter, "GetResult"), new Arguments (0)).Resolve (rc); return new Invocation (new MemberAccess (fe_awaiter, "GetResult"), new Arguments (0)).Resolve (rc);
} else {
var mg_result = MethodGroupExpr.CreatePredefined (get_result, fe_awaiter.Type, loc);
mg_result.InstanceExpression = fe_awaiter;
return new GetResultInvocation (mg_result, new Arguments (0));
} }
var mg_result = MethodGroupExpr.CreatePredefined (awaiter_definition.GetResult, fe_awaiter.Type, loc);
mg_result.InstanceExpression = fe_awaiter;
return new GetResultInvocation (mg_result, new Arguments (0));
} }
public void EmitPrologue (EmitContext ec) public void EmitPrologue (EmitContext ec)
@ -247,7 +251,7 @@ namespace Mono.CSharp
dargs.Add (new Argument (completed_expr)); dargs.Add (new Argument (completed_expr));
completed_expr = new DynamicConversion (ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve (rc); completed_expr = new DynamicConversion (ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve (rc);
} else { } else {
var pe = PropertyExpr.CreatePredefined (is_completed, loc); var pe = PropertyExpr.CreatePredefined (awaiter_definition.IsCompleted, loc);
pe.InstanceExpression = fe_awaiter; pe.InstanceExpression = fe_awaiter;
completed_expr = pe; completed_expr = pe;
} }
@ -309,9 +313,8 @@ namespace Mono.CSharp
if (!base.Resolve (bc)) if (!base.Resolve (bc))
return false; return false;
Arguments args = new Arguments (0);
type = expr.Type; type = expr.Type;
Arguments args = new Arguments (0);
// //
// The await expression is of dynamic type // The await expression is of dynamic type
@ -343,44 +346,22 @@ namespace Mono.CSharp
} }
var awaiter_type = ama.Type; var awaiter_type = ama.Type;
expr = ama;
// awaiter_definition = bc.Module.GetAwaiter (awaiter_type);
// Predefined: bool IsCompleted { get; }
//
is_completed = MemberCache.FindMember (awaiter_type, MemberFilter.Property ("IsCompleted", bc.Module.Compiler.BuiltinTypes.Bool),
BindingRestriction.InstanceOnly) as PropertySpec;
if (is_completed == null || !is_completed.HasGet) { if (!awaiter_definition.IsValidPattern) {
Error_WrongAwaiterPattern (bc, awaiter_type); Error_WrongAwaiterPattern (bc, awaiter_type);
return false; return false;
} }
// if (!awaiter_definition.INotifyCompletion) {
// 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;
}
//
// Predefined: INotifyCompletion.OnCompleted (System.Action)
//
var nc = bc.Module.PredefinedTypes.INotifyCompletion;
if (nc.Define () && !awaiter_type.ImplementsInterface (nc.TypeSpec, false)) {
bc.Report.Error (4027, loc, "The awaiter type `{0}' must implement interface `{1}'", bc.Report.Error (4027, loc, "The awaiter type `{0}' must implement interface `{1}'",
awaiter_type.GetSignatureForError (), nc.GetSignatureForError ()); awaiter_type.GetSignatureForError (), bc.Module.PredefinedTypes.INotifyCompletion.GetSignatureForError ());
return false; return false;
} }
result_type = get_result.ReturnType; expr = ama;
result_type = awaiter_definition.GetResult.ReturnType;
return true; return true;
} }

45
ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs

@ -1366,22 +1366,12 @@ namespace Mono.CSharp
if (proxy_method == null) { if (proxy_method == null) {
string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count); string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
var base_parameters = new Parameter[method.Parameters.Count];
for (int i = 0; i < base_parameters.Length; ++i) {
var base_param = method.Parameters.FixedParameters[i];
base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location),
base_param.Name, base_param.ModFlags, null, Location);
base_parameters[i].Resolve (this, i);
}
var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
if (method.Parameters.HasArglist) {
cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
}
MemberName member_name; MemberName member_name;
TypeArguments targs = null; TypeArguments targs = null;
TypeSpec return_type = method.ReturnType;
var local_param_types = method.Parameters.Types;
if (method.IsGeneric) { if (method.IsGeneric) {
// //
// Copy all base generic method type parameters info // Copy all base generic method type parameters info
@ -1393,19 +1383,42 @@ namespace Mono.CSharp
targs.Arguments = new TypeSpec[hoisted_tparams.Length]; targs.Arguments = new TypeSpec[hoisted_tparams.Length];
for (int i = 0; i < hoisted_tparams.Length; ++i) { for (int i = 0; i < hoisted_tparams.Length; ++i) {
var tp = hoisted_tparams[i]; var tp = hoisted_tparams[i];
tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null)); var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
tparams.Add (local_tp);
targs.Add (new SimpleName (tp.Name, Location)); targs.Add (new SimpleName (tp.Name, Location));
targs.Arguments[i] = tp; targs.Arguments[i] = local_tp.Type;
} }
member_name = new MemberName (name, tparams, Location); member_name = new MemberName (name, tparams, Location);
//
// Mutate any method type parameters from original
// to newly created hoisted version
//
var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
return_type = mutator.Mutate (return_type);
local_param_types = mutator.Mutate (local_param_types);
} else { } else {
member_name = new MemberName (name); member_name = new MemberName (name);
} }
var base_parameters = new Parameter[method.Parameters.Count];
for (int i = 0; i < base_parameters.Length; ++i) {
var base_param = method.Parameters.FixedParameters[i];
base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
base_param.Name, base_param.ModFlags, null, Location);
base_parameters[i].Resolve (this, i);
}
var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
if (method.Parameters.HasArglist) {
cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
}
// Compiler generated proxy // Compiler generated proxy
proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location), proxy_method = new Method (this, new TypeExpression (return_type, Location),
Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN, Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
member_name, cloned_params, null); member_name, cloned_params, null);

50
ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs

@ -704,7 +704,7 @@ namespace Mono.CSharp {
if (expr.Type == InternalType.Arglist) if (expr.Type == InternalType.Arglist)
return target_type == ec.Module.PredefinedTypes.ArgIterator.TypeSpec; return target_type == ec.Module.PredefinedTypes.ArgIterator.TypeSpec;
return ImplicitUserConversion (ec, expr, target_type, Location.Null) != null; return UserDefinedConversion (ec, expr, target_type, true, true, Location.Null) != null;
} }
// //
@ -917,17 +917,20 @@ namespace Mono.CSharp {
// //
static TypeSpec FindMostSpecificSource (List<MethodSpec> list, TypeSpec sourceType, Expression source, bool apply_explicit_conv_rules) static TypeSpec FindMostSpecificSource (List<MethodSpec> list, TypeSpec sourceType, Expression source, bool apply_explicit_conv_rules)
{ {
var src_types_set = new TypeSpec [list.Count]; TypeSpec[] src_types_set = null;
// //
// Try exact match first, if any operator converts from S then Sx = S // Try exact match first, if any operator converts from S then Sx = S
// //
for (int i = 0; i < src_types_set.Length; ++i) { for (int i = 0; i < list.Count; ++i) {
TypeSpec param_type = list [i].Parameters.Types [0]; TypeSpec param_type = list [i].Parameters.Types [0];
if (param_type == sourceType) if (param_type == sourceType)
return param_type; return param_type;
if (src_types_set == null)
src_types_set = new TypeSpec [list.Count];
src_types_set [i] = param_type; src_types_set [i] = param_type;
} }
@ -961,7 +964,7 @@ namespace Mono.CSharp {
static public TypeSpec FindMostSpecificTarget (IList<MethodSpec> list, static public TypeSpec FindMostSpecificTarget (IList<MethodSpec> list,
TypeSpec target, bool apply_explicit_conv_rules) TypeSpec target, bool apply_explicit_conv_rules)
{ {
var tgt_types_set = new List<TypeSpec> (); List<TypeSpec> tgt_types_set = null;
// //
// If any operator converts to T then Tx = T // If any operator converts to T then Tx = T
@ -971,6 +974,12 @@ namespace Mono.CSharp {
if (ret_type == target) if (ret_type == target)
return ret_type; return ret_type;
if (tgt_types_set == null) {
tgt_types_set = new List<TypeSpec> (list.Count);
} else if (tgt_types_set.Contains (ret_type)) {
continue;
}
tgt_types_set.Add (ret_type); tgt_types_set.Add (ret_type);
} }
@ -1005,7 +1014,7 @@ namespace Mono.CSharp {
/// </summary> /// </summary>
static public Expression ImplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc) static public Expression ImplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc)
{ {
return UserDefinedConversion (ec, source, target, true, loc); return UserDefinedConversion (ec, source, target, true, false, loc);
} }
/// <summary> /// <summary>
@ -1013,7 +1022,7 @@ namespace Mono.CSharp {
/// </summary> /// </summary>
static Expression ExplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc) static Expression ExplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc)
{ {
return UserDefinedConversion (ec, source, target, false, loc); return UserDefinedConversion (ec, source, target, false, false, loc);
} }
static void FindApplicableUserDefinedConversionOperators (IList<MemberSpec> operators, Expression source, TypeSpec target, bool implicitOnly, ref List<MethodSpec> candidates) static void FindApplicableUserDefinedConversionOperators (IList<MemberSpec> operators, Expression source, TypeSpec target, bool implicitOnly, ref List<MethodSpec> candidates)
@ -1077,7 +1086,7 @@ namespace Mono.CSharp {
// //
// User-defined conversions // User-defined conversions
// //
static Expression UserDefinedConversion (ResolveContext ec, Expression source, TypeSpec target, bool implicitOnly, Location loc) static Expression UserDefinedConversion (ResolveContext ec, Expression source, TypeSpec target, bool implicitOnly, bool probingOnly, Location loc)
{ {
List<MethodSpec> candidates = null; List<MethodSpec> candidates = null;
@ -1173,19 +1182,24 @@ namespace Mono.CSharp {
} }
if (most_specific_operator == null) { if (most_specific_operator == null) {
MethodSpec ambig_arg = null; //
foreach (var candidate in candidates) { // Unless running in probing more
if (candidate.ReturnType == t_x) //
most_specific_operator = candidate; if (!probingOnly) {
else if (candidate.Parameters.Types[0] == s_x) MethodSpec ambig_arg = null;
ambig_arg = candidate; foreach (var candidate in candidates) {
if (candidate.ReturnType == t_x)
most_specific_operator = candidate;
else if (candidate.Parameters.Types[0] == s_x)
ambig_arg = candidate;
}
ec.Report.Error (457, loc,
"Ambiguous user defined operators `{0}' and `{1}' when converting from `{2}' to `{3}'",
ambig_arg.GetSignatureForError (), most_specific_operator.GetSignatureForError (),
source.Type.GetSignatureForError (), target.GetSignatureForError ());
} }
ec.Report.Error (457, loc,
"Ambiguous user defined operators `{0}' and `{1}' when converting from `{2}' to `{3}'",
ambig_arg.GetSignatureForError (), most_specific_operator.GetSignatureForError (),
source.Type.GetSignatureForError (), target.GetSignatureForError ());
return ErrorExpression.Instance; return ErrorExpression.Instance;
} }
} }

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

File diff suppressed because it is too large Load Diff

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

@ -951,10 +951,10 @@ struct_declaration
opt_partial opt_partial
STRUCT STRUCT
{ {
lexer.ConstraintsParsing = true;
} }
type_declaration_name type_declaration_name
{ {
lexer.ConstraintsParsing = true;
push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4));
} }
@ -1539,7 +1539,7 @@ fixed_parameter
: opt_attributes : opt_attributes
opt_parameter_modifier opt_parameter_modifier
parameter_type parameter_type
IDENTIFIER identifier_inside_body
{ {
var lt = (Tokenizer.LocatedToken) $4; var lt = (Tokenizer.LocatedToken) $4;
$$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
@ -1548,7 +1548,7 @@ fixed_parameter
| opt_attributes | opt_attributes
opt_parameter_modifier opt_parameter_modifier
parameter_type parameter_type
IDENTIFIER OPEN_BRACKET CLOSE_BRACKET identifier_inside_body OPEN_BRACKET CLOSE_BRACKET
{ {
var lt = (Tokenizer.LocatedToken) $4; var lt = (Tokenizer.LocatedToken) $4;
report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name"); report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
@ -1574,7 +1574,7 @@ fixed_parameter
| opt_attributes | opt_attributes
opt_parameter_modifier opt_parameter_modifier
parameter_type parameter_type
IDENTIFIER identifier_inside_body
ASSIGN ASSIGN
{ {
++lexer.parsing_block; ++lexer.parsing_block;
@ -1952,10 +1952,10 @@ interface_declaration
opt_partial opt_partial
INTERFACE INTERFACE
{ {
lexer.ConstraintsParsing = true;
} }
type_declaration_name type_declaration_name
{ {
lexer.ConstraintsParsing = true;
push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4));
} }
@ -3219,28 +3219,28 @@ parenthesized_expression
; ;
member_access member_access
: primary_expression DOT IDENTIFIER opt_type_argument_list : primary_expression DOT identifier_inside_body opt_type_argument_list
{ {
var lt = (Tokenizer.LocatedToken) $3; var lt = (Tokenizer.LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) { $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) {
DotLocation = GetLocation ($2) DotLocation = GetLocation ($2)
}; };
} }
| builtin_types DOT IDENTIFIER opt_type_argument_list | builtin_types DOT identifier_inside_body opt_type_argument_list
{ {
var lt = (Tokenizer.LocatedToken) $3; var lt = (Tokenizer.LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) { $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) {
DotLocation = GetLocation ($2) DotLocation = GetLocation ($2)
}; };
} }
| BASE DOT IDENTIFIER opt_type_argument_list | BASE DOT identifier_inside_body opt_type_argument_list
{ {
var lt = (Tokenizer.LocatedToken) $3; var lt = (Tokenizer.LocatedToken) $3;
$$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location) { $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location) {
DotLocation = GetLocation ($2) DotLocation = GetLocation ($2)
}; };
} }
| qualified_alias_member IDENTIFIER opt_type_argument_list | qualified_alias_member identifier_inside_body opt_type_argument_list
{ {
var lt1 = (Tokenizer.LocatedToken) $1; var lt1 = (Tokenizer.LocatedToken) $1;
var lt2 = (Tokenizer.LocatedToken) $2; var lt2 = (Tokenizer.LocatedToken) $2;
@ -3344,6 +3344,12 @@ member_initializer
$$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
lbag.AddLocation ($$, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| AWAIT ASSIGN initializer_value
{
var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1);
$$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| GENERATE_COMPLETION | GENERATE_COMPLETION
{ {
$$ = new CompletionElementInitializer (null, GetLocation ($1)); $$ = new CompletionElementInitializer (null, GetLocation ($1));
@ -3680,13 +3686,13 @@ anonymous_type_parameters
; ;
anonymous_type_parameter anonymous_type_parameter
: IDENTIFIER ASSIGN variable_initializer : identifier_inside_body ASSIGN variable_initializer
{ {
var lt = (Tokenizer.LocatedToken)$1; var lt = (Tokenizer.LocatedToken)$1;
$$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
lbag.AddLocation ($$, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| IDENTIFIER | identifier_inside_body
{ {
var lt = (Tokenizer.LocatedToken)$1; var lt = (Tokenizer.LocatedToken)$1;
$$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
@ -4537,6 +4543,11 @@ lambda_parameter
var lt = (Tokenizer.LocatedToken) $1; var lt = (Tokenizer.LocatedToken) $1;
$$ = new ImplicitLambdaParameter (lt.Value, lt.Location); $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
} }
| AWAIT
{
var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1);
$$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
}
; ;
opt_lambda_parameter_list opt_lambda_parameter_list
@ -4593,6 +4604,17 @@ lambda_expression
$$ = end_anonymous ((ParametersBlock) $4); $$ = end_anonymous ((ParametersBlock) $4);
lbag.AddLocation ($$, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| AWAIT ARROW
{
var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1);
Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $4);
lbag.AddLocation ($$, GetLocation ($2));
}
| ASYNC identifier_inside_body ARROW | ASYNC identifier_inside_body ARROW
{ {
var lt = (Tokenizer.LocatedToken) $2; var lt = (Tokenizer.LocatedToken) $2;
@ -4687,10 +4709,11 @@ class_declaration
opt_partial opt_partial
CLASS CLASS
{ {
lexer.ConstraintsParsing = true;
} }
type_declaration_name type_declaration_name
{ {
lexer.ConstraintsParsing = true;
Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1); Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1);
if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) { if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) {
FeatureIsNotAvailable (c.Location, "static classes"); FeatureIsNotAvailable (c.Location, "static classes");
@ -5303,10 +5326,7 @@ identifier_inside_body
: IDENTIFIER : IDENTIFIER
| AWAIT | AWAIT
{ {
if (async_block) { $$ = Error_AwaitAsIdentifier ($1);
report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
$$ = new Tokenizer.LocatedToken ("await", GetLocation ($1));
}
} }
; ;
@ -7059,6 +7079,16 @@ void Error_MissingInitializer (Location loc)
report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration"); report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration");
} }
object Error_AwaitAsIdentifier (object token)
{
if (async_block) {
report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression");
return new Tokenizer.LocatedToken ("await", GetLocation (token));
}
return token;
}
void push_current_container (TypeDefinition tc, object partial_token) void push_current_container (TypeDefinition tc, object partial_token)
{ {
if (module.Evaluator != null){ if (module.Evaluator != null){

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

@ -197,7 +197,7 @@ namespace Mono.CSharp
readonly int tab_size; readonly int tab_size;
bool handle_get_set = false; bool handle_get_set = false;
bool handle_remove_add = false; bool handle_remove_add = false;
bool handle_where = false; bool handle_where;
bool handle_typeof = false; bool handle_typeof = false;
bool lambda_arguments_parsing; bool lambda_arguments_parsing;
List<Location> escaped_identifiers; List<Location> escaped_identifiers;
@ -710,7 +710,7 @@ namespace Mono.CSharp
} }
break; break;
case Token.WHERE: case Token.WHERE:
if (!handle_where && !query_parsing) if (!(handle_where && current_token != Token.COLON) && !query_parsing)
res = -1; res = -1;
break; break;
case Token.FROM: case Token.FROM:
@ -719,7 +719,7 @@ namespace Mono.CSharp
// followed by any token except ; , = // followed by any token except ; , =
// //
if (!query_parsing) { if (!query_parsing) {
if (lambda_arguments_parsing) { if (lambda_arguments_parsing || parsing_block == 0) {
res = -1; res = -1;
break; break;
} }
@ -742,7 +742,7 @@ namespace Mono.CSharp
case Token.UINT: case Token.UINT:
case Token.ULONG: case Token.ULONG:
next_token = xtoken (); next_token = xtoken ();
if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS) if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS || next_token == Token.ASSIGN)
goto default; goto default;
res = Token.FROM_FIRST; res = Token.FROM_FIRST;
@ -782,6 +782,7 @@ namespace Mono.CSharp
case Token.NAMESPACE: case Token.NAMESPACE:
// TODO: some explanation needed // TODO: some explanation needed
check_incorrect_doc_comment (); check_incorrect_doc_comment ();
parsing_modifiers = false;
break; break;
case Token.PARTIAL: case Token.PARTIAL:
@ -817,6 +818,15 @@ namespace Mono.CSharp
return token (); return token ();
} }
// HACK: A token is not a keyword so we need to restore identifiers buffer
// which has been overwritten before we grabbed the identifier
id_builder[0] = 'p';
id_builder[1] = 'a';
id_builder[2] = 'r';
id_builder[3] = 't';
id_builder[4] = 'i';
id_builder[5] = 'a';
id_builder[6] = 'l';
res = -1; res = -1;
break; break;
@ -839,8 +849,10 @@ namespace Mono.CSharp
case Token.IDENTIFIER: case Token.IDENTIFIER:
PushPosition (); PushPosition ();
xtoken (); xtoken ();
if (xtoken () != Token.ARROW) if (xtoken () != Token.ARROW) {
PopPosition ();
goto default; goto default;
}
PopPosition (); PopPosition ();
break; break;
@ -964,8 +976,12 @@ namespace Mono.CSharp
// //
// Expression inside parens is single type, (int[]) // Expression inside parens is single type, (int[])
// //
if (is_type) if (is_type) {
if (current_token == Token.SEMICOLON)
return Token.OPEN_PARENS;
return Token.OPEN_PARENS_CAST; return Token.OPEN_PARENS_CAST;
}
// //
// Expression is possible cast, look at next token, (T)null // Expression is possible cast, look at next token, (T)null
@ -1022,6 +1038,7 @@ namespace Mono.CSharp
continue; continue;
case Token.IDENTIFIER: case Token.IDENTIFIER:
case Token.AWAIT:
switch (ptoken) { switch (ptoken) {
case Token.DOT: case Token.DOT:
if (bracket_level == 0) { if (bracket_level == 0) {
@ -1274,6 +1291,7 @@ namespace Mono.CSharp
case Token.OP_GENERICS_GT: case Token.OP_GENERICS_GT:
case Token.INTERR: case Token.INTERR:
case Token.OP_COALESCING: case Token.OP_COALESCING:
case Token.COLON:
next_token = Token.INTERR_NULLABLE; next_token = Token.INTERR_NULLABLE;
break; break;
@ -1412,7 +1430,7 @@ namespace Mono.CSharp
// if we have not seen anything in between // if we have not seen anything in between
// report this error // report this error
// //
Report.Warning (78, 4, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)"); Report.Warning (78, 4, Location, "The `l' suffix is easily confused with the digit `1' (use `L' for clarity)");
} }
goto case 'L'; goto case 'L';

29
ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs

@ -175,28 +175,31 @@ namespace Mono.CSharp
bool keep_include_node = false; bool keep_include_node = false;
string file = el.GetAttribute ("file"); string file = el.GetAttribute ("file");
string path = el.GetAttribute ("path"); string path = el.GetAttribute ("path");
if (file == "") { if (file == "") {
Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute"); Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute");
el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
keep_include_node = true; keep_include_node = true;
} } else if (path.Length == 0) {
else if (path.Length == 0) {
Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute"); Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute");
el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
keep_include_node = true; keep_include_node = true;
} } else {
else {
XmlDocument doc; XmlDocument doc;
if (!StoredDocuments.TryGetValue (file, out doc)) { Exception exception = null;
var full_path = Path.Combine (Path.GetDirectoryName (mc.Location.NameFullPath), file);
if (!StoredDocuments.TryGetValue (full_path, out doc)) {
try { try {
doc = new XmlDocument (); doc = new XmlDocument ();
doc.Load (file); doc.Load (full_path);
StoredDocuments.Add (file, doc); StoredDocuments.Add (full_path, doc);
} catch (Exception) { } catch (Exception e) {
exception = e;
el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file `{0}': cannot be included ", file)), el); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file `{0}': cannot be included ", file)), el);
Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- `{0}'", file);
} }
} }
if (doc != null) { if (doc != null) {
try { try {
XmlNodeList nl = doc.SelectNodes (path); XmlNodeList nl = doc.SelectNodes (path);
@ -208,11 +211,17 @@ namespace Mono.CSharp
foreach (XmlNode n in nl) foreach (XmlNode n in nl)
el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el); el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el);
} catch (Exception ex) { } catch (Exception ex) {
exception = ex;
el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el);
Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}' ({2})", path, file, ex.Message);
} }
} }
if (exception != null) {
Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}'. {2}",
path, file, exception.Message);
}
} }
return keep_include_node; return keep_include_node;
} }

40
ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs

@ -1067,7 +1067,10 @@ namespace Mono.CSharp {
if (es == null) if (es == null)
Error_InvalidExpressionStatement (ec); Error_InvalidExpressionStatement (ec);
if (!(e is Assign) && (e.Type.IsGenericTask || e.Type == ec.Module.PredefinedTypes.Task.TypeSpec)) { //
// This is quite expensive warning, try to limit the damage
//
if (MemberAccess.IsValidDotExpression (e.Type) && !(e is Assign || e is Await)) {
WarningAsyncWithoutWait (ec, e); WarningAsyncWithoutWait (ec, e);
} }
@ -1077,6 +1080,30 @@ namespace Mono.CSharp {
static void WarningAsyncWithoutWait (BlockContext bc, Expression e) static void WarningAsyncWithoutWait (BlockContext bc, Expression e)
{ {
if (bc.CurrentAnonymousMethod is AsyncInitializer) { if (bc.CurrentAnonymousMethod is AsyncInitializer) {
var awaiter = new AwaitStatement.AwaitableMemberAccess (e) {
ProbingMode = true
};
//
// Need to do full resolve because GetAwaiter can be extension method
// available only in this context
//
var mg = awaiter.Resolve (bc) as MethodGroupExpr;
if (mg == null)
return;
var arguments = new Arguments (0);
mg = mg.OverloadResolve (bc, ref arguments, null, OverloadResolver.Restrictions.ProbingOnly);
if (mg == null)
return;
//
// Use same check rules as for real await
//
var awaiter_definition = bc.Module.GetAwaiter (mg.BestCandidateReturnType);
if (!awaiter_definition.IsValidPattern || !awaiter_definition.INotifyCompletion)
return;
bc.Report.Warning (4014, 1, e.Location, bc.Report.Warning (4014, 1, e.Location,
"The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator"); "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator");
return; return;
@ -3523,7 +3550,7 @@ namespace Mono.CSharp {
best_candidate_return = best_candidate.ReturnType; best_candidate_return = best_candidate.ReturnType;
} }
if (best_candidate.IsGeneric && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) { if (best_candidate.IsGeneric && (restr & OverloadResolver.Restrictions.ProbingOnly) == 0 && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) {
ConstraintChecker cc = new ConstraintChecker (ec); ConstraintChecker cc = new ConstraintChecker (ec);
cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc); cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc);
} }
@ -4915,7 +4942,7 @@ namespace Mono.CSharp {
} }
} }
if (invocable_member != null) { if (invocable_member != null && !IsProbingOnly) {
rc.Report.SymbolRelatedToPreviousError (best_candidate); rc.Report.SymbolRelatedToPreviousError (best_candidate);
rc.Report.SymbolRelatedToPreviousError (invocable_member); rc.Report.SymbolRelatedToPreviousError (invocable_member);
rc.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and invocable non-method `{1}'. Using method group", rc.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and invocable non-method `{1}'. Using method group",
@ -4937,7 +4964,7 @@ namespace Mono.CSharp {
// //
// Don't run possibly expensive checks in probing mode // Don't run possibly expensive checks in probing mode
// //
if (!rc.IsInProbingMode) { if (!IsProbingOnly && !rc.IsInProbingMode) {
// //
// Check ObsoleteAttribute on the best method // Check ObsoleteAttribute on the best method
// //
@ -6528,8 +6555,9 @@ namespace Mono.CSharp {
// Don't capture temporary variables except when using // Don't capture temporary variables except when using
// state machine redirection and block yields // state machine redirection and block yields
// //
if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator && if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer &&
ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) { (ec.CurrentBlock.Explicit.HasYield || ec.CurrentBlock.Explicit.HasAwait) &&
ec.IsVariableCapturingRequired) {
AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec); AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
storey.CaptureLocalVariable (ec, li); storey.CaptureLocalVariable (ec, li);
} }

9
ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs

@ -223,9 +223,16 @@ namespace Mono.CSharp
bool partial_input; bool partial_input;
CSharpParser parser = ParseString (ParseMode.Silent, input, out partial_input); CSharpParser parser = ParseString (ParseMode.Silent, input, out partial_input);
// Terse mode, try to provide the trailing semicolon automatically.
if (parser == null && Terse && partial_input){ if (parser == null && Terse && partial_input){
bool ignore; bool ignore;
parser = ParseString (ParseMode.Silent, input + ";", out ignore);
// check if the source would compile with a block, if so, we should not
// add the semicolon.
var needs_block = ParseString (ParseMode.Silent, input + "{}", out ignore) != null;
if (!needs_block)
parser = ParseString (ParseMode.Silent, input + ";", out ignore);
} }
if (parser == null){ if (parser == null){
compiled = null; compiled = null;

47
ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -4659,6 +4659,8 @@ namespace Mono.CSharp
} }
true_expr = conv; true_expr = conv;
if (true_expr.Type != type)
true_expr = EmptyCast.Create (true_expr, type);
} else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) { } else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) {
false_expr = conv; false_expr = conv;
} else { } else {
@ -4696,6 +4698,18 @@ namespace Mono.CSharp
expr.EmitBranchable (ec, false_target, false); expr.EmitBranchable (ec, false_target, false);
true_expr.Emit (ec); true_expr.Emit (ec);
//
// Verifier doesn't support interface merging. When there are two types on
// the stack without common type hint and the common type is an interface.
// Use temporary local to give verifier hint on what type to unify the stack
//
if (type.IsInterface && true_expr is EmptyCast && false_expr is EmptyCast) {
var temp = ec.GetTemporaryLocal (type);
ec.Emit (OpCodes.Stloc, temp);
ec.Emit (OpCodes.Ldloc, temp);
ec.FreeTemporaryLocal (temp, type);
}
ec.Emit (OpCodes.Br, end_target); ec.Emit (OpCodes.Br, end_target);
ec.MarkLabel (false_target); ec.MarkLabel (false_target);
false_expr.Emit (ec); false_expr.Emit (ec);
@ -7258,7 +7272,7 @@ namespace Mono.CSharp
} }
} }
public class RefValueExpr : ShimExpression public class RefValueExpr : ShimExpression, IAssignMethod
{ {
FullNamedExpression texpr; FullNamedExpression texpr;
@ -7296,6 +7310,11 @@ namespace Mono.CSharp
return this; return this;
} }
public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
{
return DoResolve (rc);
}
public override void Emit (EmitContext ec) public override void Emit (EmitContext ec)
{ {
expr.Emit (ec); expr.Emit (ec);
@ -7303,6 +7322,32 @@ namespace Mono.CSharp
ec.EmitLoadFromPtr (type); ec.EmitLoadFromPtr (type);
} }
public void Emit (EmitContext ec, bool leave_copy)
{
throw new NotImplementedException ();
}
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
{
expr.Emit (ec);
ec.Emit (OpCodes.Refanyval, type);
source.Emit (ec);
LocalTemporary temporary = null;
if (leave_copy) {
ec.Emit (OpCodes.Dup);
temporary = new LocalTemporary (source.Type);
temporary.Store (ec);
}
ec.EmitStoreFromPtr (type);
if (temporary != null) {
temporary.Emit (ec);
temporary.Release (ec);
}
}
public override object Accept (StructuralVisitor visitor) public override object Accept (StructuralVisitor visitor)
{ {
return visitor.Visit (this); return visitor.Visit (this);

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

@ -364,7 +364,7 @@ namespace Mono.CSharp {
Constraints constraints; Constraints constraints;
GenericTypeParameterBuilder builder; GenericTypeParameterBuilder builder;
TypeParameterSpec spec; readonly TypeParameterSpec spec;
public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance) public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
: base (null, name, attrs) : base (null, name, attrs)
@ -1480,6 +1480,7 @@ namespace Mono.CSharp {
{ {
readonly TypeParameters mvar; readonly TypeParameters mvar;
readonly TypeParameters var; readonly TypeParameters var;
readonly TypeParameterSpec[] src;
Dictionary<TypeSpec, TypeSpec> mutated_typespec; Dictionary<TypeSpec, TypeSpec> mutated_typespec;
public TypeParameterMutator (TypeParameters mvar, TypeParameters var) public TypeParameterMutator (TypeParameters mvar, TypeParameters var)
@ -1491,6 +1492,15 @@ namespace Mono.CSharp {
this.var = var; this.var = var;
} }
public TypeParameterMutator (TypeParameterSpec[] srcVar, TypeParameters destVar)
{
if (srcVar.Length != destVar.Count)
throw new ArgumentException ();
this.src = srcVar;
this.var = destVar;
}
#region Properties #region Properties
public TypeParameters MethodTypeParameters { public TypeParameters MethodTypeParameters {
@ -1530,9 +1540,16 @@ namespace Mono.CSharp {
public TypeParameterSpec Mutate (TypeParameterSpec tp) public TypeParameterSpec Mutate (TypeParameterSpec tp)
{ {
for (int i = 0; i < mvar.Count; ++i) { if (mvar != null) {
if (mvar[i].Type == tp) for (int i = 0; i < mvar.Count; ++i) {
return var[i].Type; if (mvar[i].Type == tp)
return var[i].Type;
}
} else {
for (int i = 0; i < src.Length; ++i) {
if (src[i] == tp)
return var[i].Type;
}
} }
return tp; return tp;
@ -3440,7 +3457,7 @@ namespace Mono.CSharp {
var invoke = Delegate.GetInvokeMethod (t); var invoke = Delegate.GetInvokeMethod (t);
TypeSpec rtype = invoke.ReturnType; TypeSpec rtype = invoke.ReturnType;
if (!rtype.IsGenericParameter && !TypeManager.IsGenericType (rtype)) if (!IsReturnTypeNonDependent (ec, invoke, rtype))
return 0; return 0;
// LAMESPEC: Standard does not specify that all methodgroup arguments // LAMESPEC: Standard does not specify that all methodgroup arguments
@ -3453,9 +3470,6 @@ namespace Mono.CSharp {
if (inflated == null) if (inflated == null)
return 0; return 0;
if (IsUnfixed (inflated) >= 0)
return 0;
param_types[i] = inflated; param_types[i] = inflated;
} }

41
ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs

@ -113,6 +113,7 @@ namespace Mono.CSharp
readonly Dictionary<TypeSpec, PointerContainer> pointer_types; readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
readonly Dictionary<TypeSpec, ReferenceContainer> reference_types; readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
readonly Dictionary<TypeSpec, MethodSpec> attrs_cache; readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
AssemblyDefinition assembly; AssemblyDefinition assembly;
readonly CompilerContext context; readonly CompilerContext context;
@ -144,6 +145,7 @@ namespace Mono.CSharp
pointer_types = new Dictionary<TypeSpec, PointerContainer> (); pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
reference_types = new Dictionary<TypeSpec, ReferenceContainer> (); reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
attrs_cache = new Dictionary<TypeSpec, MethodSpec> (); attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
} }
#region Properties #region Properties
@ -424,7 +426,7 @@ namespace Mono.CSharp
if (OptAttributes != null) if (OptAttributes != null)
OptAttributes.Emit (); OptAttributes.Emit ();
if (Compiler.Settings.Unsafe) { if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
var pa = PredefinedAttributes.UnverifiableCode; var pa = PredefinedAttributes.UnverifiableCode;
if (pa.IsDefined) if (pa.IsDefined)
pa.EmitAttribute (builder); pa.EmitAttribute (builder);
@ -472,6 +474,43 @@ namespace Mono.CSharp
return null; return null;
} }
//
// Return container with awaiter definition. It never returns null
// but all container member can be null for easier error reporting
//
public AwaiterDefinition GetAwaiter (TypeSpec type)
{
AwaiterDefinition awaiter;
if (awaiters.TryGetValue (type, out awaiter))
return awaiter;
awaiter = new AwaiterDefinition ();
//
// Predefined: bool IsCompleted { get; }
//
awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
BindingRestriction.InstanceOnly) as PropertySpec;
//
// Predefined: GetResult ()
//
// The method return type is also result type of await expression
//
awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
ParametersCompiled.EmptyReadOnlyParameters, null),
BindingRestriction.InstanceOnly) as MethodSpec;
//
// Predefined: INotifyCompletion.OnCompleted (System.Action)
//
var nc = PredefinedTypes.INotifyCompletion;
awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
awaiters.Add (type, awaiter);
return awaiter;
}
public override void GetCompletionStartingWith (string prefix, List<string> results) public override void GetCompletionStartingWith (string prefix, List<string> results)
{ {
var names = Evaluator.GetVarNames (); var names = Evaluator.GetVarNames ();

4
ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs

@ -378,8 +378,10 @@ namespace Mono.CSharp {
if (mode != LookupMode.Normal) if (mode != LookupMode.Normal)
continue; continue;
if (ts.MemberDefinition.IsImported) if (ts.MemberDefinition.IsImported) {
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts); ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
}
ctx.Module.Compiler.Report.Warning (436, 2, loc, ctx.Module.Compiler.Report.Warning (436, 2, loc,
"The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition", "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",

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

@ -649,7 +649,7 @@ namespace Mono.CSharp {
// //
// This line is useful when debugging recorded messages // This line is useful when debugging recorded messages
// //
// Console.WriteLine ("RECORDING: {0}", msg.ToString ()); // Console.WriteLine ("RECORDING: {0}", msg.Text);
if (session_messages == null) if (session_messages == null)
session_messages = new List<AbstractMessage> (); session_messages = new List<AbstractMessage> ();

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

@ -853,7 +853,7 @@ namespace Mono.CSharp {
if (ec.CurrentIterator != null) { if (ec.CurrentIterator != null) {
Error_ReturnFromIterator (ec); Error_ReturnFromIterator (ec);
} else { } else if (ec.ReturnType != InternalType.ErrorType) {
ec.Report.Error (126, loc, ec.Report.Error (126, loc,
"An object of a type convertible to `{0}' is required for the return statement", "An object of a type convertible to `{0}' is required for the return statement",
ec.ReturnType.GetSignatureForError ()); ec.ReturnType.GetSignatureForError ());
@ -2303,10 +2303,9 @@ namespace Mono.CSharp {
if (!s.Resolve (ec)) { if (!s.Resolve (ec)) {
ok = false; ok = false;
if (ec.IsInProbingMode) if (!ec.IsInProbingMode)
break; statements [ix] = new EmptyStatement (s.loc);
statements [ix] = new EmptyStatement (s.loc);
continue; continue;
} }
@ -2560,12 +2559,14 @@ namespace Mono.CSharp {
if (b.Explicit == b.Explicit.ParametersBlock && b.Explicit.ParametersBlock.StateMachine != null) { if (b.Explicit == b.Explicit.ParametersBlock && b.Explicit.ParametersBlock.StateMachine != null) {
storey.HoistedThis = b.Explicit.ParametersBlock.StateMachine.HoistedThis; storey.HoistedThis = b.Explicit.ParametersBlock.StateMachine.HoistedThis;
break;
if (storey.HoistedThis != null)
break;
} }
} }
// //
// We are the first storey on path and this has to be hoisted // We are the first storey on path and 'this' has to be hoisted
// //
if (storey.HoistedThis == null) { if (storey.HoistedThis == null) {
foreach (ExplicitBlock ref_block in Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock) { foreach (ExplicitBlock ref_block in Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock) {
@ -2581,8 +2582,9 @@ namespace Mono.CSharp {
if (block_on_path == null) if (block_on_path == null)
continue; continue;
if (storey.HoistedThis == null) if (storey.HoistedThis == null) {
storey.AddCapturedThisField (ec); storey.AddCapturedThisField (ec);
}
for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) { for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) {
if (b.AnonymousMethodStorey != null) { if (b.AnonymousMethodStorey != null) {
@ -4190,11 +4192,17 @@ namespace Mono.CSharp {
constant_section = default_section; constant_section = default_section;
} else { } else {
// //
// Store switch expression for comparission purposes // Store switch expression for comparison purposes
// //
value = new_expr as VariableReference; value = new_expr as VariableReference;
if (value == null) if (value == null) {
// Create temporary variable inside switch scope
var block = ec.CurrentBlock;
ec.CurrentBlock = Block;
value = TemporaryVariableReference.Create (SwitchType, ec.CurrentBlock, loc); value = TemporaryVariableReference.Create (SwitchType, ec.CurrentBlock, loc);
value.Resolve (ec);
ec.CurrentBlock = block;
}
} }
bool first = true; bool first = true;
@ -6126,7 +6134,7 @@ namespace Mono.CSharp {
if (mg != null) { if (mg != null) {
mg.InstanceExpression = expr; mg.InstanceExpression = expr;
Arguments args = new Arguments (0); Arguments args = new Arguments (0);
mg = mg.OverloadResolve (rc, ref args, this, OverloadResolver.Restrictions.None); mg = mg.OverloadResolve (rc, ref args, this, OverloadResolver.Restrictions.ProbingOnly);
// For ambiguous GetEnumerator name warning CS0278 was reported, but Option 2 could still apply // For ambiguous GetEnumerator name warning CS0278 was reported, but Option 2 could still apply
if (ambiguous_getenumerator_name) if (ambiguous_getenumerator_name)

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

@ -969,6 +969,19 @@ namespace Mono.CSharp
} }
} }
public class AwaiterDefinition
{
public PropertySpec IsCompleted { get; set; }
public MethodSpec GetResult { get; set; }
public bool INotifyCompletion { get; set; }
public bool IsValidPattern {
get {
return IsCompleted != null && GetResult != null && IsCompleted.HasGet;
}
}
}
partial class TypeManager { partial class TypeManager {
/// <summary> /// <summary>

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

@ -12,6 +12,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Linq;
#if STATIC #if STATIC
using MetaType = IKVM.Reflection.Type; using MetaType = IKVM.Reflection.Type;
@ -389,11 +390,16 @@ namespace Mono.CSharp
// When resolving base class of X`1 we inflate context type A`1 // When resolving base class of X`1 we inflate context type A`1
// All this happens before we even hit IFoo resolve. Without // All this happens before we even hit IFoo resolve. Without
// additional expansion any inside usage of A<T> would miss IFoo // additional expansion any inside usage of A<T> would miss IFoo
// interface because it comes from early inflated TypeSpec // interface because it comes from early inflated A`1 definition.
// //
if (inflated_instances != null) { if (inflated_instances != null) {
foreach (var inflated in inflated_instances) { //
inflated.Value.AddInterface (iface); // Inflate only existing instances not any new instances added
// during AddInterface
//
var inflated_existing = inflated_instances.Values.ToArray ();
foreach (var inflated in inflated_existing) {
inflated.AddInterface (iface);
} }
} }

Loading…
Cancel
Save