//
// 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
{
+ public enum LookupMode
+ {
+ Normal = 0,
+ Probing = 1,
+ IgnoreAccessibility = 2
+ }
+
//
// Implemented by elements which can act as independent contexts
// during resolve phase. Used mostly for lookups.
//
// 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
bool IsObsolete { get; }
bool IsUnsafe { get; }
bool IsStatic { get; }
- bool HasUnresolvedConstraints { get; }
string GetSignatureForError ();
- IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope);
- FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104);
+ ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity);
+ FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc);
FullNamedExpression LookupNamespaceAlias (string name);
}
{
FlowBranching current_flow_branching;
- TypeSpec return_type;
-
- /// <summary>
- /// The location where return has to jump to return the
- /// value
- /// </summary>
- public Label ReturnLabel; // TODO: It's emit dependant
-
- /// <summary>
- /// If we already defined the ReturnLabel
- /// </summary>
- public bool HasReturnLabel;
+ readonly TypeSpec return_type;
public int FlowOffset;
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 current_flow_branching; }
}
+ public TypeSpec ReturnType {
+ 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 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);
current_flow_branching = current_flow_branching.Parent;
}
- //
- // This method is used during the Resolution phase to flag the
- // need to define the ReturnLabel
- //
+#if !STATIC
public void NeedReturnLabel ()
{
- if (!HasReturnLabel)
- HasReturnLabel = true;
- }
-
- public TypeSpec ReturnType {
- get { return return_type; }
}
+#endif
}
//
UsingInitializerScope = 1 << 12,
+ 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; }
}
get { return (flags & Options.DoFlowAnalysis) != 0; }
}
- public bool HasUnresolvedConstraints {
- get { return false; }
- }
-
public bool IsInProbingMode {
get {
return (flags & Options.ProbingMode) != 0;
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;
}
return MemberContext.GetSignatureForError ();
}
- public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
+ public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
{
- return MemberContext.LookupExtensionMethod (extensionType, name, arity, ref scope);
+ return MemberContext.LookupExtensionMethod (extensionType, name, arity);
}
- public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
{
- return MemberContext.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
+ return MemberContext.LookupNamespaceOrType (name, arity, mode, loc);
}
public FullNamedExpression LookupNamespaceAlias (string name)
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,
- /// <summary>
- /// The constant check state is always set to `true' and cant be changed
- /// from the command line. The source code can change this setting with
- /// the `checked' and `unchecked' statements and expressions.
- /// </summary>
- ConstantCheckState = 1 << 1,
-
- AllCheckStateFlags = CheckedScope | ConstantCheckState,
+ AccurateDebugInfo = 1 << 1,
OmitDebugInfo = 1 << 2,
- ConstructorScope = 1 << 3
+ ConstructorScope = 1 << 3,
+
+ AsyncBody = 1 << 4
}
// utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements
}
}
- Options flags;
+ protected Options flags;
public bool HasSet (Options options)
{
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 ());
+ }
+ }
}