//
// Copyright 2001, 2002, 2003 Ximian, Inc.
// Copyright 2004-2009 Novell, Inc.
+// Copyright 2011 Xamarin Inc.
//
using System;
using System.Collections.Generic;
using System.IO;
-
-#if STATIC
-using IKVM.Reflection.Emit;
-#else
-using System.Reflection.Emit;
-#endif
+using System.Security.Cryptography;
namespace Mono.CSharp
{
//
// A scope type parameters either VAR or MVAR
//
- TypeParameter[] CurrentTypeParameters { get; }
+ TypeParameters CurrentTypeParameters { get; }
//
// A member definition of the context. For partial types definition use
if (rc.HasSet (ResolveContext.Options.CheckedScope))
flags |= ResolveContext.Options.CheckedScope;
+
+ if (rc.IsInProbingMode)
+ flags |= ResolveContext.Options.ProbingMode;
+
+ if (rc.HasSet (ResolveContext.Options.FieldInitializerScope))
+ flags |= ResolveContext.Options.FieldInitializerScope;
+
+ if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
+ flags |= ResolveContext.Options.ExpressionTreeConversion;
+
+ if (rc.HasSet (ResolveContext.Options.BaseInitializer))
+ flags |= ResolveContext.Options.BaseInitializer;
}
public override FlowBranching CurrentBranching {
get { return return_type; }
}
+ public bool IsUnreachable {
+ get {
+ return HasSet (Options.UnreachableScope);
+ }
+ set {
+ flags = value ? flags | Options.UnreachableScope : flags & ~Options.UnreachableScope;
+ }
+ }
+
+ public bool UnreachableReported {
+ get {
+ return HasSet (Options.UnreachableReported);
+ }
+ set {
+ flags = value ? flags | Options.UnreachableReported : flags & ~Options.UnreachableScope;
+ }
+ }
+
// <summary>
// Starts a new code branching. This inherits the state of all local
// variables and parameters from the current branching.
return branching;
}
- public FlowBranchingException StartFlowBranching (ExceptionStatement stmt)
+ public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt)
{
- FlowBranchingException branching = new FlowBranchingException (CurrentBranching, stmt);
+ FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt);
current_flow_branching = branching;
return branching;
}
return branching;
}
- public FlowBranchingIterator StartFlowBranching (StateMachineInitializer iterator, FlowBranching parent)
+ public FlowBranchingIterator StartFlowBranching (Iterator iterator, FlowBranching parent)
{
FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator);
current_flow_branching = branching;
return branching;
}
+ public FlowBranchingAsync StartFlowBranching (AsyncInitializer asyncBody, FlowBranching parent)
+ {
+ var branching = new FlowBranchingAsync (parent, asyncBody);
+ current_flow_branching = branching;
+ return branching;
+ }
+
public FlowBranchingToplevel StartFlowBranching (ParametersBlock stmt, FlowBranching parent)
{
FlowBranchingToplevel branching = new FlowBranchingToplevel (parent, stmt);
LockScope = 1 << 13,
+ UnreachableScope = 1 << 14,
+
+ UnreachableReported = 1 << 15,
+
/// <summary>
/// Whether control flow analysis is enabled
/// </summary>
get { return MemberContext.CurrentType; }
}
- public TypeParameter[] CurrentTypeParameters {
+ public TypeParameters CurrentTypeParameters {
get { return MemberContext.CurrentTypeParameters; }
}
if (CurrentAnonymousMethod == null)
return false;
- // FIXME: IsIterator is too aggressive, we should capture only if child
- // block contains yield
+ //
+ // Capture only if this or any of child blocks contain yield
+ // or it's a parameter
+ //
if (CurrentAnonymousMethod.IsIterator)
- return true;
+ return local.IsParameter || local.Block.Explicit.HasYield;
+
+ //
+ // Capture only if this or any of child blocks contain await
+ // or it's a parameter
+ //
+ if (CurrentAnonymousMethod is AsyncInitializer)
+ return local.IsParameter || local.Block.Explicit.HasAwait || CurrentBlock.Explicit.HasAwait;
return local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original;
}
Dictionary<string, SourceFile> all_source_files;
- public CompilerContext (CompilerSettings settings, Report report)
+ public CompilerContext (CompilerSettings settings, ReportPrinter reportPrinter)
{
this.settings = settings;
- this.report = report;
+ this.report = new Report (this, reportPrinter);
this.builtin_types = new BuiltinTypes ();
this.TimeReporter = DisabledTimeReporter;
}
}
}
- public List<CompilationSourceFile> SourceFiles {
+ public List<SourceFile> SourceFiles {
get {
return settings.SourceFiles;
}
string path;
if (!Path.IsPathRooted (name)) {
- string root = Path.GetDirectoryName (comp_unit.FullPathName);
+ string root = Path.GetDirectoryName (comp_unit.SourceFile.FullPathName);
path = Path.Combine (root, name);
} else
path = name;
if (all_source_files.TryGetValue (path, out retval))
return retval;
- retval = Location.AddFile (name, path);
+ retval = new SourceFile (name, path, all_source_files.Count + 1);
+ Location.AddFile (retval);
all_source_files.Add (path, retval);
return retval;
}
/// </summary>
CheckedScope = 1 << 0,
+ AccurateDebugInfo = 1 << 1,
+
OmitDebugInfo = 1 << 2,
ConstructorScope = 1 << 3,
return new FlagsHandle (this, options, enable ? options : 0);
}
}
+
+ //
+ // Parser session objects. We could recreate all these objects for each parser
+ // instance but the best parser performance the session object can be reused
+ //
+ public class ParserSession
+ {
+ MD5 md5;
+
+ public readonly char[] StreamReaderBuffer = new char[SeekableStreamReader.DefaultReadAheadSize * 2];
+ public readonly Dictionary<char[], string>[] Identifiers = new Dictionary<char[], string>[Tokenizer.MaxIdentifierLength + 1];
+ public readonly List<Parameter> ParametersStack = new List<Parameter> (4);
+ public readonly char[] IDBuilder = new char[Tokenizer.MaxIdentifierLength];
+ public readonly char[] NumberBuilder = new char[Tokenizer.MaxNumberLength];
+
+ public LocationsBag LocationsBag { get; set; }
+ public bool UseJayGlobalArrays { get; set; }
+ public Tokenizer.LocatedToken[] LocatedTokens { get; set; }
+
+ public MD5 GetChecksumAlgorithm ()
+ {
+ return md5 ?? (md5 = MD5.Create ());
+ }
+ }
}