From 96c93497a0877820da0ed4a2a0dde468bfccfa84 Mon Sep 17 00:00:00 2001 From: Jon Hanna Date: Thu, 15 Feb 2018 20:37:30 +0000 Subject: [PATCH] Make many helpers, factories and tables static in Microsoft.CSharp (dotnet/corefx#27044) * Have TypeArray in charge of the empty TypeArray singleton * Make TypeArray allocation a static responsibility of TypeArray * Remove some orphaned members. Mostly BSYMMGR-returning members that had been used to allocate TypeArrays * Make members static were possible. Those that can already be easily made static. Includes removing some members that this makes no longer necessary. * Remove unused parameters Since some are of the types we'll be making static, and such parameters will have to go anyway. * Make TypeTable static And more conventional names within TypeTable. * More TypeManager state & methods to static * Make SYMTBL.Key an immutable struct. * SYMTBL completely static and renamed to SymbolStore More conventional name, and doesn't clash with other SymbolTable class. * GetWinRTCollectionIfacesAll to property. * SymFactory static class. * Remove PredefinedTypes._symbolManager field Only used in assertion. * Remove assert comparison with this in GetAggregate Assert is the only reason to not be static, allows a cascade of more changes to static. * Make InternalsVisibleTo check static. * Make cycle of instance methods static Take quite a large set of methods which must be instance because of cyclic instance dependencies, and make them all static. Removes dependency in AggregateSymbol and NullableType on TypeManager instances. * Replace GetAggTypeSym with virtual method on CType. Merged with existing GetAts on NullableType. Comment says this would be nice, and indeed it would, and its easy now. * Make those members that can now be static, static. * Remove orphaned members and fields. * PredefinedMembers entirely static. * Remove UserStringBuilder.m_buildingInProgress Only used in asserts, just assert on whether m_strBuilder is null or not. Also rename m_strBuilder to _strBuilder to be more conventional. * Favour returning over out in UserStringBuilder And favour clearing StringBuilder over creating another. * Make ErrorHandling completely static. Creating UserStringBuilder instances on demand. * TypeManager static. * Make CNullable methods static and merge directly into ExpressionBinder Don't cache method and property, as they're already cached. * Don't preload types. Either they'll be loaded soon anyway, or else it's a wasted effort. * Move CompareTypes into Better.cs * Remove BSYMMGR.LookupAggMember Just call into SymbolStore.LookupSym * Move LookupNextSym logic into Symbol * Remove BSYMMGR and GlobalSymbolContext No longer any use. * ExprFactory static * SymbolLoader static * CSemanticChecker static * Don't pre-emptively load System.Object Will be loaded as a base of the first type encountered anyway. * SymbolTable static * More methods can be made static * Remove orphaned method. * Move methods for getting MemberInfos from expressions into those expressions * Replace ExpressionTreeCallRewriter.GetObject with virtual property in Expr * TypeArray tidy-up. * Pass ExpressionBinder to operator delegates, and make them static. Allows array to be created once statically, rather than on each instance construction. * Create RuntimeBinder, ExpressionBinder and BindingContext per operation These are now very lightweight, so it's simpler to create them anew each time rather than overwriting the values in the BindingContext. * Make RuntimeBinder, ExpressionBinder and BindingContext structs No need to allocate on the heap. * Remove AggregateDeclaration We only ever care about the AggregateSymbol it relates to. (The two aren't really separate in dynamic code, where there aren't really declarations). * Remove IsChecked and CallingContext from C# binders. Now not used as they are passed to RuntimeBinder on construction, except for CallingContext remaining in CSharpInvokeMemberBinder for use in deferring. * Make RecordBinOpSigFromArgs static. A last member that can be made static. * Make static-member-only classes static. * Make NameHashKey a readonly struct. Commit migrated from https://github.com/dotnet/corefx/commit/b7d1ae93c179510991f75709c3c3c1d3e3d062c1 --- .../Microsoft.CSharp/src/Microsoft.CSharp.csproj | 5 +- .../RuntimeBinder/CSharpBinaryOperationBinder.cs | 18 +- .../CSharp/RuntimeBinder/CSharpConvertBinder.cs | 18 +- .../CSharp/RuntimeBinder/CSharpGetIndexBinder.cs | 13 +- .../CSharp/RuntimeBinder/CSharpGetMemberBinder.cs | 13 +- .../CSharp/RuntimeBinder/CSharpInvokeBinder.cs | 13 +- .../RuntimeBinder/CSharpInvokeConstructorBinder.cs | 11 +- .../RuntimeBinder/CSharpInvokeMemberBinder.cs | 10 +- .../CSharp/RuntimeBinder/CSharpIsEventBinder.cs | 11 +- .../CSharp/RuntimeBinder/CSharpSetIndexBinder.cs | 14 +- .../CSharp/RuntimeBinder/CSharpSetMemberBinder.cs | 14 +- .../RuntimeBinder/CSharpUnaryOperationBinder.cs | 14 +- .../CSharp/RuntimeBinder/Errors/ErrorHandling.cs | 15 +- .../RuntimeBinder/Errors/UserStringBuilder.cs | 96 ++---- .../RuntimeBinder/ExpressionTreeCallRewriter.cs | 321 +----------------- .../CSharp/RuntimeBinder/ICSharpBinder.cs | 6 +- .../CSharp/RuntimeBinder/RuntimeBinder.cs | 359 ++++++++------------ .../CSharp/RuntimeBinder/Semantics/BinOpArgInfo.cs | 2 +- .../CSharp/RuntimeBinder/Semantics/BinOpSig.cs | 6 +- .../RuntimeBinder/Semantics/Binding/Better.cs | 86 ++++- .../RuntimeBinder/Semantics/BindingContext.cs | 29 +- .../CSharp/RuntimeBinder/Semantics/Conversion.cs | 87 +++-- .../CSharp/RuntimeBinder/Semantics/Conversions.cs | 42 +-- .../Semantics/Declarations/AggregateDeclaration.cs | 37 --- .../RuntimeBinder/Semantics/EXPRExtensions.cs | 9 +- .../RuntimeBinder/Semantics/ExplicitConversion.cs | 32 +- .../CSharp/RuntimeBinder/Semantics/ExprFactory.cs | 133 ++++---- .../RuntimeBinder/Semantics/ExpressionBinder.cs | 309 ++++++------------ .../RuntimeBinder/Semantics/GlobalSymbolContext.cs | 36 -- .../RuntimeBinder/Semantics/GroupToArgsBinder.cs | 158 ++++----- .../Semantics/GroupToArgsBinderResult.cs | 2 +- .../RuntimeBinder/Semantics/ImplicitConversion.cs | 39 +-- .../CSharp/RuntimeBinder/Semantics/MemberLookup.cs | 83 ++--- .../RuntimeBinder/Semantics/MemberLookupResults.cs | 12 +- .../RuntimeBinder/Semantics/MethodIterator.cs | 21 +- .../RuntimeBinder/Semantics/MethodTypeInferrer.cs | 44 +-- .../CSharp/RuntimeBinder/Semantics/Nullable.cs | 81 +---- .../CSharp/RuntimeBinder/Semantics/Operators.cs | 363 ++++++++++++--------- .../RuntimeBinder/Semantics/PredefinedMembers.cs | 164 +++------- .../RuntimeBinder/Semantics/SemanticChecker.cs | 68 +--- .../Semantics/Symbols/AggregateSymbol.cs | 29 +- .../RuntimeBinder/Semantics/Symbols/FieldSymbol.cs | 4 +- .../Symbols/NamespaceOrAggregateSymbol.cs | 41 --- .../RuntimeBinder/Semantics/Symbols/SymFactory.cs | 71 ++-- .../RuntimeBinder/Semantics/Symbols/Symbol.cs | 18 +- .../RuntimeBinder/Semantics/Symbols/SymbolKind.cs | 1 - .../Semantics/Symbols/SymbolLoader.cs | 127 ++----- .../Semantics/Symbols/SymbolManagerBase.cs | 304 ----------------- .../Symbols/{SymbolTable.cs => SymbolStore.cs} | 51 +-- .../CSharp/RuntimeBinder/Semantics/Tree/Cast.cs | 14 + .../RuntimeBinder/Semantics/Tree/Constant.cs | 64 ++++ .../CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs | 11 + .../RuntimeBinder/Semantics/Tree/ExprWithType.cs | 6 +- .../RuntimeBinder/Semantics/Tree/MemberGroup.cs | 4 +- .../RuntimeBinder/Semantics/Tree/MethodInfo.cs | 134 ++++++++ .../RuntimeBinder/Semantics/Tree/PropertyInfo.cs | 59 ++++ .../CSharp/RuntimeBinder/Semantics/Tree/TypeOf.cs | 2 + .../Tree/Visitors/ExpressionTreeRewriter.cs | 180 +++++----- .../RuntimeBinder/Semantics/Tree/ZeroInitialize.cs | 4 + .../CSharp/RuntimeBinder/Semantics/TypeBind.cs | 40 +-- .../RuntimeBinder/Semantics/Types/AggregateType.cs | 37 ++- .../RuntimeBinder/Semantics/Types/ArrayType.cs | 3 + .../RuntimeBinder/Semantics/Types/NullableType.cs | 10 +- .../Semantics/Types/PredefinedTypes.cs | 33 +- .../CSharp/RuntimeBinder/Semantics/Types/Type.cs | 8 + .../RuntimeBinder/Semantics/Types/TypeArray.cs | 128 +++++++- .../RuntimeBinder/Semantics/Types/TypeManager.cs | 222 +++++-------- .../RuntimeBinder/Semantics/Types/TypeTable.cs | 133 ++++---- .../CSharp/RuntimeBinder/Semantics/UnaOpSig.cs | 4 +- .../Microsoft/CSharp/RuntimeBinder/SymbolTable.cs | 310 ++++++++---------- 70 files changed, 1895 insertions(+), 2951 deletions(-) delete mode 100644 src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/AggregateDeclaration.cs delete mode 100644 src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GlobalSymbolContext.cs delete mode 100644 src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolManagerBase.cs rename src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/{SymbolTable.cs => SymbolStore.cs} (63%) diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj index 5438b70..e59037c 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj +++ b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj @@ -56,7 +56,6 @@ - @@ -64,7 +63,6 @@ - @@ -94,9 +92,8 @@ - - + diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpBinaryOperationBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpBinaryOperationBinder.cs index 36f2d39..3f42229 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpBinaryOperationBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpBinaryOperationBinder.cs @@ -13,7 +13,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic binary operation in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic binary operation in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpBinaryOperationBinder : BinaryOperationBinder, ICSharpBinder @@ -33,24 +33,20 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.BindBinaryOperation(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) { string name = Operation.GetCLROperatorName(); Debug.Assert(name != null); - symbolTable.PopulateSymbolTableWithName(name, null, arguments[0].Type); - symbolTable.PopulateSymbolTableWithName(name, null, arguments[1].Type); + SymbolTable.PopulateSymbolTableWithName(name, null, arguments[0].Type); + SymbolTable.PopulateSymbolTableWithName(name, null, arguments[1].Type); } public bool IsBinderThatCanHaveRefReceiver => false; - public bool IsChecked { get; } - internal bool IsLogicalOperation => (_binopFlags & CSharpBinaryOperationFlags.LogicalOperation) != 0; private readonly CSharpBinaryOperationFlags _binopFlags; - public Type CallingContext { get; } - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -63,7 +59,7 @@ namespace Microsoft.CSharp.RuntimeBinder /// Initializes a new instance of the class. /// /// The binary operation kind. - /// True if the operation is defined in a checked context; otherwise false. + /// True if the operation is defined in a checked context; otherwise false. /// The flags associated with this binary operation. /// The that indicates where this operation is defined. /// The sequence of instances for the arguments to this operation. @@ -75,12 +71,10 @@ namespace Microsoft.CSharp.RuntimeBinder IEnumerable argumentInfo) : base(operation) { - IsChecked = isChecked; _binopFlags = binaryOperationFlags; - CallingContext = callingContext; _argumentInfo = BinderHelper.ToArray(argumentInfo); Debug.Assert(_argumentInfo.Length == 2); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext, isChecked); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpConvertBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpConvertBinder.cs index a45684e..56993a4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpConvertBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpConvertBinder.cs @@ -11,7 +11,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic conversion in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic conversion in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpConvertBinder : ConvertBinder, ICSharpBinder @@ -36,11 +36,11 @@ namespace Microsoft.CSharp.RuntimeBinder : runtimeBinder.BindImplicitConversion(arguments, Type, locals, ConversionKind == CSharpConversionKind.ArrayCreationConversion); } - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) { // Conversions don't need to do anything, since they're just conversions! // After we add payload information, we add conversions for all argument - // types anyway, so that will get handled there. + // types anyway, so that will get handled there. } public bool IsBinderThatCanHaveRefReceiver => false; @@ -49,10 +49,6 @@ namespace Microsoft.CSharp.RuntimeBinder private CSharpConversionKind ConversionKind { get; } - public bool IsChecked { get; } - - public Type CallingContext { get; } - private readonly RuntimeBinder _binder; /// @@ -70,9 +66,7 @@ namespace Microsoft.CSharp.RuntimeBinder base(type, conversionKind == CSharpConversionKind.ExplicitConversion) { ConversionKind = conversionKind; - IsChecked = isChecked; - CallingContext = callingContext; - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext, isChecked); } /// @@ -83,13 +77,13 @@ namespace Microsoft.CSharp.RuntimeBinder /// The representing the result of the binding. public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion) { -#if ENABLECOMBINDER +#if ENABLECOMBINDER DynamicMetaObject com; if (!BinderHelper.IsWindowsRuntimeObject(target) && ComBinder.TryConvert(this, target, out com)) { return com; } -#endif +#endif BinderHelper.ValidateBindArgument(target, nameof(target)); return BinderHelper.Bind(this, _binder, new[] { target }, null, errorSuggestion); } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetIndexBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetIndexBinder.cs index be3f828..2a1aa6c 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetIndexBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetIndexBinder.cs @@ -10,7 +10,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic indexer access in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic indexer access in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpGetIndexBinder : GetIndexBinder, ICSharpBinder @@ -25,15 +25,11 @@ namespace Microsoft.CSharp.RuntimeBinder return runtimeBinder.BindProperty(this, arguments[0], locals[0], indexerArguments); } - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(SpecialNames.Indexer, null, arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(SpecialNames.Indexer, null, arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => true; - public Type CallingContext { get; } - - public bool IsChecked => false; - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -50,9 +46,8 @@ namespace Microsoft.CSharp.RuntimeBinder IEnumerable argumentInfo) : base(BinderHelper.CreateCallInfo(ref argumentInfo, 1)) // discard 1 argument: the target object { - CallingContext = callingContext; _argumentInfo = argumentInfo as CSharpArgumentInfo[]; - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetMemberBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetMemberBinder.cs index 19290dd..8bccb1e 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetMemberBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpGetMemberBinder.cs @@ -11,7 +11,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic property access in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic property access in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpGetMemberBinder : GetMemberBinder, IInvokeOnGetBinder, ICSharpBinder @@ -24,15 +24,11 @@ namespace Microsoft.CSharp.RuntimeBinder return runtimeBinder.BindProperty(this, arguments[0], locals[0], null); } - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => false; - public Type CallingContext { get; } - - public bool IsChecked => false; - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -58,9 +54,8 @@ namespace Microsoft.CSharp.RuntimeBinder base(name, false /*caseInsensitive*/) { ResultIndexed = resultIndexed; - CallingContext = callingContext; _argumentInfo = BinderHelper.ToArray(argumentInfo); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeBinder.cs index 4a7fa73..ca1842e 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeBinder.cs @@ -10,7 +10,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic delegate-like call in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic delegate-like call in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpInvokeBinder : InvokeBinder, ICSharpInvokeOrInvokeMemberBinder @@ -20,8 +20,8 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.DispatchPayload(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(symbolTable, this, callingType, arguments); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments); public bool IsBinderThatCanHaveRefReceiver => true; @@ -35,10 +35,6 @@ namespace Microsoft.CSharp.RuntimeBinder private readonly CSharpCallFlags _flags; - public Type CallingContext { get; } - - public bool IsChecked => false; - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -60,9 +56,8 @@ namespace Microsoft.CSharp.RuntimeBinder base(BinderHelper.CreateCallInfo(ref argumentInfo, 1)) // discard 1 argument: the target object (even if static, arg is type) { _flags = flags; - CallingContext = callingContext; _argumentInfo = argumentInfo as CSharpArgumentInfo[]; - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeConstructorBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeConstructorBinder.cs index 5d61c0c..ebac399 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeConstructorBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeConstructorBinder.cs @@ -16,17 +16,13 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.DispatchPayload(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(symbolTable, this, callingType, arguments); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments); public bool IsBinderThatCanHaveRefReceiver => true; public CSharpCallFlags Flags { get; } - public Type CallingContext { get; } - - public bool IsChecked => false; - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -47,9 +43,8 @@ namespace Microsoft.CSharp.RuntimeBinder IEnumerable argumentInfo) { Flags = flags; - CallingContext = callingContext; _argumentInfo = BinderHelper.ToArray(argumentInfo); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeMemberBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeMemberBinder.cs index b5fbbd0..2c00860 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeMemberBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpInvokeMemberBinder.cs @@ -11,7 +11,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic method call in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic method call in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpInvokeMemberBinder : InvokeMemberBinder, ICSharpInvokeOrInvokeMemberBinder @@ -21,8 +21,8 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.DispatchPayload(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(symbolTable, this, callingType, arguments); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments); public bool IsBinderThatCanHaveRefReceiver => true; @@ -32,8 +32,6 @@ namespace Microsoft.CSharp.RuntimeBinder public Type CallingContext { get; } - public bool IsChecked => false; - public Type[] TypeArguments { get; } private readonly CSharpArgumentInfo[] _argumentInfo; @@ -71,7 +69,7 @@ namespace Microsoft.CSharp.RuntimeBinder CallingContext = callingContext; TypeArguments = BinderHelper.ToArray(typeArguments); _argumentInfo = BinderHelper.ToArray(argumentInfo); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpIsEventBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpIsEventBinder.cs index 7425880..dfb0eba 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpIsEventBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpIsEventBinder.cs @@ -18,8 +18,8 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.BindIsEvent(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Info.IsStaticType ? arguments[0].Value as Type : arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Info.IsStaticType ? arguments[0].Value as Type : arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => false; @@ -27,10 +27,6 @@ namespace Microsoft.CSharp.RuntimeBinder public string Name { get; } - public Type CallingContext { get; } - - public bool IsChecked => false; - private readonly RuntimeBinder _binder; /// @@ -43,8 +39,7 @@ namespace Microsoft.CSharp.RuntimeBinder Type callingContext) { Name = name; - CallingContext = callingContext; - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetIndexBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetIndexBinder.cs index 37bd58a..6e36118 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetIndexBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetIndexBinder.cs @@ -10,7 +10,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic indexer access in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic indexer access in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpSetIndexBinder : SetIndexBinder, ICSharpBinder @@ -22,17 +22,13 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.BindAssignment(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(SpecialNames.Indexer, null, arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(SpecialNames.Indexer, null, arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => true; internal bool IsCompoundAssignment { get; } - public bool IsChecked { get; } - - public Type CallingContext { get; } - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -56,10 +52,8 @@ namespace Microsoft.CSharp.RuntimeBinder base(BinderHelper.CreateCallInfo(ref argumentInfo, 2)) // discard 2 arguments: the target object and the value { IsCompoundAssignment = isCompoundAssignment; - IsChecked = isChecked; - CallingContext = callingContext; _argumentInfo = argumentInfo as CSharpArgumentInfo[]; - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext, isChecked); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetMemberBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetMemberBinder.cs index ddf4611..fb0ea5f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetMemberBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpSetMemberBinder.cs @@ -10,7 +10,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic property access in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic property access in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpSetMemberBinder : SetMemberBinder, ICSharpBinder @@ -20,17 +20,13 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.BindAssignment(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => false; internal bool IsCompoundAssignment { get; } - public bool IsChecked { get; } - - public Type CallingContext { get; } - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -57,10 +53,8 @@ namespace Microsoft.CSharp.RuntimeBinder base(name, false) { IsCompoundAssignment = isCompoundAssignment; - IsChecked = isChecked; - CallingContext = callingContext; _argumentInfo = BinderHelper.ToArray(argumentInfo); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext, isChecked); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpUnaryOperationBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpUnaryOperationBinder.cs index 2b94e5c..b9d477b 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpUnaryOperationBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/CSharpUnaryOperationBinder.cs @@ -13,7 +13,7 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder { /// - /// Represents a dynamic unary operation in C#, providing the binding semantics and the details about the operation. + /// Represents a dynamic unary operation in C#, providing the binding semantics and the details about the operation. /// Instances of this class are generated by the C# compiler. /// internal sealed class CSharpUnaryOperationBinder : UnaryOperationBinder, ICSharpBinder @@ -34,15 +34,11 @@ namespace Microsoft.CSharp.RuntimeBinder public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals) => runtimeBinder.BindUnaryOperation(this, arguments, locals); - public void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments) - => symbolTable.PopulateSymbolTableWithName(Operation.GetCLROperatorName(), null, arguments[0].Type); + public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments) + => SymbolTable.PopulateSymbolTableWithName(Operation.GetCLROperatorName(), null, arguments[0].Type); public bool IsBinderThatCanHaveRefReceiver => false; - public bool IsChecked { get; } - - public Type CallingContext { get; } - private readonly CSharpArgumentInfo[] _argumentInfo; CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index) => _argumentInfo[index]; @@ -63,11 +59,9 @@ namespace Microsoft.CSharp.RuntimeBinder IEnumerable argumentInfo) : base(operation) { - IsChecked = isChecked; - CallingContext = callingContext; _argumentInfo = BinderHelper.ToArray(argumentInfo); Debug.Assert(_argumentInfo.Length == 1); - _binder = RuntimeBinder.GetInstance(); + _binder = new RuntimeBinder(callingContext, isChecked); } /// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/ErrorHandling.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/ErrorHandling.cs index ded6351..d7f9503 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/ErrorHandling.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/ErrorHandling.cs @@ -9,16 +9,9 @@ using Microsoft.CSharp.RuntimeBinder.Semantics; namespace Microsoft.CSharp.RuntimeBinder.Errors { - internal sealed class ErrorHandling + internal static class ErrorHandling { - private readonly UserStringBuilder _userStringBuilder; - - public ErrorHandling(GlobalSymbolContext globalSymbols) - { - _userStringBuilder = new UserStringBuilder(globalSymbols); - } - - public RuntimeBinderException Error(ErrorCode id, params ErrArg[] args) + public static RuntimeBinderException Error(ErrorCode id, params ErrArg[] args) { // Create an argument array manually using the type information in the ErrArgs. string[] prgpsz = new string[args.Length]; @@ -28,6 +21,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors int piarg = 0; int cargUnique = 0; + UserStringBuilder builder = new UserStringBuilder(); + for (int iarg = 0; iarg < args.Length; iarg++) { ErrArg arg = args[iarg]; @@ -37,7 +32,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors continue; - if (!_userStringBuilder.ErrArgToString(out prgpsz[ppsz], arg, out bool fUserStrings)) + if (!builder.ErrArgToString(out prgpsz[ppsz], arg, out bool fUserStrings)) { if (arg.eak == ErrArgKind.Int) { diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/UserStringBuilder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/UserStringBuilder.cs index 519fd02..ba0b90b 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/UserStringBuilder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Errors/UserStringBuilder.cs @@ -10,36 +10,28 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Errors { - internal sealed class UserStringBuilder + internal struct UserStringBuilder { - private bool m_buildingInProgress; - private GlobalSymbolContext m_globalSymbols; - private StringBuilder m_strBuilder; - - public UserStringBuilder( - GlobalSymbolContext globalSymbols) - { - Debug.Assert(globalSymbols != null); - m_buildingInProgress = false; - m_globalSymbols = globalSymbols; - } + private StringBuilder _strBuilder; private void BeginString() { - Debug.Assert(!m_buildingInProgress); - m_buildingInProgress = true; - m_strBuilder = new StringBuilder(); + Debug.Assert(_strBuilder == null || _strBuilder.Length == 0); + if(_strBuilder == null) + { + _strBuilder = new StringBuilder(); + } } - private void EndString(out string s) + private string EndString() { - Debug.Assert(m_buildingInProgress); - m_buildingInProgress = false; - s = m_strBuilder.ToString(); - m_strBuilder = null; + Debug.Assert(_strBuilder != null); + string s = _strBuilder.ToString(); + _strBuilder.Clear(); + return s; } - private void ErrSK(out string psz, SYMKIND sk) + private static string ErrSK(SYMKIND sk) { MessageID id; switch (sk) @@ -74,7 +66,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors break; } - ErrId(out psz, id); + return ErrId(id); } /* * Create a fill-in string describing a parameter list. @@ -105,12 +97,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors private void ErrAppendString(string str) { - m_strBuilder.Append(str); + _strBuilder.Append(str); } private void ErrAppendChar(char ch) { - m_strBuilder.Append(ch); + _strBuilder.Append(ch); } private void ErrAppendPrintf(string format, params object[] args) @@ -143,7 +135,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors if (pctx != null && !pctx.IsNop && parent is AggregateSymbol agg && 0 != agg.GetTypeVarsAll().Count) { - CType pType = GetTypeManager().SubstType(agg.getThisType(), pctx); + CType pType = TypeManager.SubstType(agg.getThisType(), pctx); ErrAppendType(pType, null); } else @@ -153,7 +145,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors ErrAppendChar('.'); } - private void ErrAppendTypeParameters(TypeArray @params, SubstContext pctx, bool forClass) + private void ErrAppendTypeParameters(TypeArray @params, SubstContext pctx) { if (@params != null && @params.Count != 0) { @@ -175,7 +167,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors ErrAppendParentSym(meth, pctx); // Get the type args from the explicit impl type and substitute using pctx (if there is one). - SubstContext ctx = new SubstContext(GetTypeManager().SubstType(meth.swtSlot.GetType(), pctx)); + SubstContext ctx = new SubstContext(TypeManager.SubstType(meth.swtSlot.GetType(), pctx)); ErrAppendSym(meth.swtSlot.Sym, ctx, fArgs); // args already added @@ -270,13 +262,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors break; } - ErrAppendTypeParameters(meth.typeVars, pctx, false); + ErrAppendTypeParameters(meth.typeVars, pctx); if (fArgs) { // append argument types ErrAppendChar('('); - ErrAppendParamList(GetTypeManager().SubstTypeArray(meth.Params, pctx), meth.isParamArray); + ErrAppendParamList(TypeManager.SubstTypeArray(meth.Params, pctx), meth.isParamArray); ErrAppendChar(')'); } } @@ -284,7 +276,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors private void ErrAppendIndexer(IndexerSymbol indexer, SubstContext pctx) { ErrAppendString("this["); - ErrAppendParamList(GetTypeManager().SubstTypeArray(indexer.Params, pctx), indexer.isParamArray); + ErrAppendParamList(TypeManager.SubstTypeArray(indexer.Params, pctx), indexer.isParamArray); ErrAppendChar(']'); } private void ErrAppendProperty(PropertySymbol prop, SubstContext pctx) @@ -294,7 +286,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors { if (prop.swtSlot.Sym != null) { - SubstContext ctx = new SubstContext(GetTypeManager().SubstType(prop.swtSlot.GetType(), pctx)); + SubstContext ctx = new SubstContext(TypeManager.SubstType(prop.swtSlot.GetType(), pctx)); ErrAppendSym(prop.swtSlot.Sym, ctx); } else if (prop is IndexerSymbol indexer) @@ -313,16 +305,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors } } - private void ErrAppendEvent(EventSymbol @event, SubstContext pctx) - { - } - - private void ErrAppendId(MessageID id) - { - string str; - ErrId(out str, id); - ErrAppendString(str); - } + private void ErrAppendId(MessageID id) => ErrAppendString(ErrId(id)); /* * Create a fill-in string describing a symbol. @@ -336,10 +319,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors { switch (sym.getKind()) { - case SYMKIND.SK_AggregateDeclaration: - ErrAppendSym(((AggregateDeclaration)sym).Agg(), pctx); - break; - case SYMKIND.SK_AggregateSymbol: { // Check for a predefined class with a special "nice" name for @@ -354,7 +333,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors { ErrAppendParentSym(sym, pctx); ErrAppendName(sym.name); - ErrAppendTypeParameters(((AggregateSymbol)sym).GetTypeVars(), pctx, true); + ErrAppendTypeParameters(((AggregateSymbol)sym).GetTypeVars(), pctx); } break; } @@ -368,7 +347,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors break; case SYMKIND.SK_EventSymbol: - ErrAppendEvent((EventSymbol)sym, pctx); break; case SYMKIND.SK_NamespaceSymbol: @@ -418,7 +396,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors { if (pctx != null && !pctx.IsNop) { - pType = GetTypeManager().SubstType(pType, pctx); + pType = TypeManager.SubstType(pType, pctx); } switch (pType.TypeKind) @@ -451,7 +429,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors ErrAppendName(pAggType.OwningAggregate.name); } - ErrAppendTypeParameters(pAggType.TypeArgsThis, null, true); + ErrAppendTypeParameters(pAggType.TypeArgsThis, null); break; } @@ -570,18 +548,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors switch (parg.eak) { case ErrArgKind.SymKind: - ErrSK(out psz, parg.sk); + psz = ErrSK(parg.sk); break; case ErrArgKind.Type: BeginString(); ErrAppendType(parg.pType, null); - EndString(out psz); + psz = EndString(); fUserStrings = true; break; case ErrArgKind.Sym: BeginString(); ErrAppendSym(parg.sym, null); - EndString(out psz); + psz = EndString(); fUserStrings = true; break; case ErrArgKind.Name: @@ -603,7 +581,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors SubstContext ctx = new SubstContext(parg.swtMemo.ats, null); BeginString(); ErrAppendSym(parg.swtMemo.sym, ctx, true); - EndString(out psz); + psz = EndString(); fUserStrings = true; break; } @@ -613,7 +591,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors SubstContext ctx = new SubstContext(parg.mpwiMemo.ats, parg.mpwiMemo.typeArgs); BeginString(); ErrAppendSym(parg.mpwiMemo.sym, ctx, true); - EndString(out psz); + psz = EndString(); fUserStrings = true; break; } @@ -625,14 +603,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Errors return result; } - private TypeManager GetTypeManager() - { - return m_globalSymbols.GetTypes(); - } - - private void ErrId(out string s, MessageID id) - { - s = ErrorFacts.GetMessage(id); - } + private static string ErrId(MessageID id) => ErrorFacts.GetMessage(id); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs index 2f287fb..0cbde82 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ExpressionTreeCallRewriter.cs @@ -29,25 +29,23 @@ namespace Microsoft.CSharp.RuntimeBinder private readonly Dictionary _DictionaryOfParameters; private readonly Expression[] _ListOfParameters; - private readonly TypeManager _typeManager; - // Counts how many EXPRSAVEs we've encountered so we know which index into the + // Counts how many EXPRSAVEs we've encountered so we know which index into the // parameter list we should be taking. private int _currentParameterIndex; ///////////////////////////////////////////////////////////////////////////////// - private ExpressionTreeCallRewriter(TypeManager typeManager, Expression[] listOfParameters) + private ExpressionTreeCallRewriter(Expression[] listOfParameters) { - _typeManager = typeManager; _DictionaryOfParameters = new Dictionary(); _ListOfParameters = listOfParameters; } ///////////////////////////////////////////////////////////////////////////////// - public static Expression Rewrite(TypeManager typeManager, ExprBinOp binOp, Expression[] listOfParameters) + public static Expression Rewrite(ExprBinOp binOp, Expression[] listOfParameters) { - ExpressionTreeCallRewriter rewriter = new ExpressionTreeCallRewriter(typeManager, listOfParameters); + ExpressionTreeCallRewriter rewriter = new ExpressionTreeCallRewriter(listOfParameters); // We should have a ExprBinOp that's an EK_SEQUENCE. The RHS of our sequence // should be a call to PM_EXPRESSION_LAMBDA. The LHS of our sequence is the @@ -260,7 +258,7 @@ namespace Microsoft.CSharp.RuntimeBinder } Expression obj = null; - MethodInfo m = GetMethodInfoFromExpr(methinfo); + MethodInfo m = methinfo.MethodInfo; Expression[] arguments = GetArgumentsFromArrayInit(arrinit); if (m == null) @@ -333,7 +331,7 @@ namespace Microsoft.CSharp.RuntimeBinder } Debug.Assert((pExpr.Flags & EXPRFLAG.EXF_UNBOXRUNTIME) == 0); - MethodInfo m = GetMethodInfoFromExpr((ExprMethodInfo)list2.OptionalNextListNode); + MethodInfo m = ((ExprMethodInfo)list2.OptionalNextListNode).MethodInfo; if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED) { @@ -395,7 +393,7 @@ namespace Microsoft.CSharp.RuntimeBinder arguments = null; } - PropertyInfo p = GetPropertyInfoFromExpr(propinfo); + PropertyInfo p = propinfo.PropertyInfo; if (p == null) { @@ -455,20 +453,19 @@ namespace Microsoft.CSharp.RuntimeBinder { ExprList list = (ExprList)pExpr.OptionalArguments; - var constructor = GetConstructorInfoFromExpr(list.OptionalElement as ExprMethodInfo); - var arguments = GetArgumentsFromArrayInit(list.OptionalNextListNode as ExprArrayInit); + ConstructorInfo constructor = ((ExprMethodInfo)list.OptionalElement).ConstructorInfo; + Expression[] arguments = GetArgumentsFromArrayInit(list.OptionalNextListNode as ExprArrayInit); return Expression.New(constructor, arguments); } ///////////////////////////////////////////////////////////////////////////////// - private Expression GenerateConstantType(ExprCall pExpr) + private static Expression GenerateConstantType(ExprCall pExpr) { ExprList list = (ExprList)pExpr.OptionalArguments; return Expression.Constant( - GetObject(list.OptionalElement), - ((ExprTypeOf)list.OptionalNextListNode).SourceType.AssociatedSystemType); + list.OptionalElement.Object, ((ExprTypeOf)list.OptionalNextListNode).SourceType.AssociatedSystemType); } ///////////////////////////////////////////////////////////////////////////////// @@ -560,11 +557,11 @@ namespace Microsoft.CSharp.RuntimeBinder ExprConstant isLifted = (ExprConstant)next.OptionalElement; Debug.Assert(isLifted != null); bIsLifted = isLifted.Val.Int32Val == 1; - methodInfo = GetMethodInfoFromExpr((ExprMethodInfo)next.OptionalNextListNode); + methodInfo = ((ExprMethodInfo)next.OptionalNextListNode).MethodInfo; } else { - methodInfo = GetMethodInfoFromExpr((ExprMethodInfo)list.OptionalNextListNode); + methodInfo = ((ExprMethodInfo)list.OptionalNextListNode).MethodInfo; } switch (pExpr.PredefinedMethod) @@ -651,7 +648,7 @@ namespace Microsoft.CSharp.RuntimeBinder PREDEFMETH pm = pExpr.PredefinedMethod; ExprList list = (ExprList)pExpr.OptionalArguments; Expression arg = GetExpression(list.OptionalElement); - MethodInfo methodInfo = GetMethodInfoFromExpr((ExprMethodInfo)list.OptionalNextListNode); + MethodInfo methodInfo = ((ExprMethodInfo)list.OptionalNextListNode).MethodInfo; switch (pm) { @@ -871,100 +868,6 @@ namespace Microsoft.CSharp.RuntimeBinder } } - ///////////////////////////////////////////////////////////////////////////////// - - private object GetObject(Expr pExpr) - { - for (;;) - { - if (pExpr is ExprCast cast) - { - pExpr = cast.Argument; - } - else if (pExpr is ExprTypeOf typeOf) - { - return typeOf.SourceType.AssociatedSystemType; - } - else if (pExpr is ExprMethodInfo methodInfo) - { - return GetMethodInfoFromExpr(methodInfo); - } - else if (pExpr is ExprConstant constant) - { - ConstVal val = constant.Val; - CType underlyingType = pExpr.Type; - object objval; - - if (underlyingType is NullType) - { - return null; - } - - switch (Type.GetTypeCode(underlyingType.AssociatedSystemType)) - { - case TypeCode.Boolean: - objval = val.BooleanVal; - break; - case TypeCode.SByte: - objval = val.SByteVal; - break; - case TypeCode.Byte: - objval = val.ByteVal; - break; - case TypeCode.Int16: - objval = val.Int16Val; - break; - case TypeCode.UInt16: - objval = val.UInt16Val; - break; - case TypeCode.Int32: - objval = val.Int32Val; - break; - case TypeCode.UInt32: - objval = val.UInt32Val; - break; - case TypeCode.Int64: - objval = val.Int64Val; - break; - case TypeCode.UInt64: - objval = val.UInt64Val; - break; - case TypeCode.Single: - objval = val.SingleVal; - break; - case TypeCode.Double: - objval = val.DoubleVal; - break; - case TypeCode.Decimal: - objval = val.DecimalVal; - break; - case TypeCode.Char: - objval = val.CharVal; - break; - case TypeCode.String: - objval = val.StringVal; - break; - default: - objval = val.ObjectVal; - break; - } - - return pExpr.Type.IsEnumType ? Enum.ToObject(pExpr.Type.AssociatedSystemType, objval) : objval; - } - else if (pExpr is ExprZeroInit zeroInit) - { - return Activator.CreateInstance(zeroInit.Type.AssociatedSystemType); - } - else - { - Debug.Assert(false, "Invalid Expr in GetObject"); - throw Error.InternalCompilerError(); - } - } - } - - ///////////////////////////////////////////////////////////////////////////////// - private Expression[] GetArgumentsFromArrayInit(ExprArrayInit arrinit) { List expressions = new List(); @@ -995,202 +898,6 @@ namespace Microsoft.CSharp.RuntimeBinder return expressions.ToArray(); } - ///////////////////////////////////////////////////////////////////////////////// - - private MethodInfo GetMethodInfoFromExpr(ExprMethodInfo methinfo) - { - // To do this, we need to construct a type array of the parameter types, - // get the parent constructed type, and get the method from it. - - AggregateType aggType = methinfo.Method.Ats; - MethodSymbol methSym = methinfo.Method.Meth(); - - TypeArray genericParams = _typeManager.SubstTypeArray(methSym.Params, aggType, methSym.typeVars); - CType genericReturn = _typeManager.SubstType(methSym.RetType, aggType, methSym.typeVars); - - Type type = aggType.AssociatedSystemType; - MethodInfo methodInfo = methSym.AssociatedMemberInfo as MethodInfo; - - // This is to ensure that for embedded nopia types, we have the - // appropriate local type from the member itself; this is possible - // because nopia types are not generic or nested. - if (!type.IsGenericType && !type.IsNested) - { - type = methodInfo.DeclaringType; - } - - // We need to find the associated methodinfo on the instantiated type. - foreach (MethodInfo m in type.GetRuntimeMethods()) - { -#if UNSUPPORTEDAPI - if ((m.MetadataToken != methodInfo.MetadataToken) || (m.Module != methodInfo.Module)) -#else - if (!m.HasSameMetadataDefinitionAs(methodInfo)) -#endif - { - continue; - } - - Debug.Assert((m.Name == methodInfo.Name) && - (m.GetParameters().Length == genericParams.Count) && - (TypesAreEqual(m.ReturnType, genericReturn.AssociatedSystemType))); - - bool bMatch = true; - ParameterInfo[] parameters = m.GetParameters(); - for (int i = 0; i < genericParams.Count; i++) - { - if (!TypesAreEqual(parameters[i].ParameterType, genericParams[i].AssociatedSystemType)) - { - bMatch = false; - break; - } - } - if (bMatch) - { - if (m.IsGenericMethod) - { - int size = methinfo.Method.TypeArgs?.Count ?? 0; - Type[] typeArgs = new Type[size]; - if (size > 0) - { - for (int i = 0; i < methinfo.Method.TypeArgs.Count; i++) - { - typeArgs[i] = methinfo.Method.TypeArgs[i].AssociatedSystemType; - } - } - return m.MakeGenericMethod(typeArgs); - } - - return m; - } - } - - Debug.Assert(false, "Could not find matching method"); - throw Error.InternalCompilerError(); - } - - ///////////////////////////////////////////////////////////////////////////////// - - private ConstructorInfo GetConstructorInfoFromExpr(ExprMethodInfo methinfo) - { - // To do this, we need to construct a type array of the parameter types, - // get the parent constructed type, and get the method from it. - - AggregateType aggType = methinfo.Method.Ats; - MethodSymbol methSym = methinfo.Method.Meth(); - - TypeArray genericInstanceParams = _typeManager.SubstTypeArray(methSym.Params, aggType); - Type type = aggType.AssociatedSystemType; - ConstructorInfo ctorInfo = (ConstructorInfo)methSym.AssociatedMemberInfo; - - // This is to ensure that for embedded nopia types, we have the - // appropriate local type from the member itself; this is possible - // because nopia types are not generic or nested. - if (!type.IsGenericType && !type.IsNested) - { - type = ctorInfo.DeclaringType; - } - - foreach (ConstructorInfo c in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) - { -#if UNSUPPORTEDAPI - if ((c.MetadataToken != ctorInfo.MetadataToken) || (c.Module != ctorInfo.Module)) -#else - if (!c.HasSameMetadataDefinitionAs(ctorInfo)) -#endif - { - continue; - } - Debug.Assert(c.GetParameters() == null || c.GetParameters().Length == genericInstanceParams.Count); - - bool bMatch = true; - ParameterInfo[] parameters = c.GetParameters(); - for (int i = 0; i < genericInstanceParams.Count; i++) - { - if (!TypesAreEqual(parameters[i].ParameterType, genericInstanceParams[i].AssociatedSystemType)) - { - bMatch = false; - break; - } - } - if (bMatch) - { - return c; - } - } - - Debug.Assert(false, "Could not find matching constructor"); - throw Error.InternalCompilerError(); - } - - ///////////////////////////////////////////////////////////////////////////////// - - private PropertyInfo GetPropertyInfoFromExpr(ExprPropertyInfo propinfo) - { - // To do this, we need to construct a type array of the parameter types, - // get the parent constructed type, and get the property from it. - - AggregateType aggType = propinfo.Property.Ats; - PropertySymbol propSym = propinfo.Property.Prop(); - - TypeArray genericInstanceParams = _typeManager.SubstTypeArray(propSym.Params, aggType, null); - - Type type = aggType.AssociatedSystemType; - PropertyInfo propertyInfo = propSym.AssociatedPropertyInfo; - - // This is to ensure that for embedded nopia types, we have the - // appropriate local type from the member itself; this is possible - // because nopia types are not generic or nested. - if (!type.IsGenericType && !type.IsNested) - { - type = propertyInfo.DeclaringType; - } - - foreach (PropertyInfo p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) - { -#if UNSUPPORTEDAPI - if ((p.MetadataToken != propertyInfo.MetadataToken) || (p.Module != propertyInfo.Module)) -#else - if (!p.HasSameMetadataDefinitionAs(propertyInfo)) - { -#endif - continue; - } - Debug.Assert((p.Name == propertyInfo.Name) && - (p.GetIndexParameters() == null || p.GetIndexParameters().Length == genericInstanceParams.Count)); - - bool bMatch = true; - ParameterInfo[] parameters = p.GetSetMethod(true) != null ? - p.GetSetMethod(true).GetParameters() : p.GetGetMethod(true).GetParameters(); - for (int i = 0; i < genericInstanceParams.Count; i++) - { - if (!TypesAreEqual(parameters[i].ParameterType, genericInstanceParams[i].AssociatedSystemType)) - { - bMatch = false; - break; - } - } - if (bMatch) - { - return p; - } - } - - Debug.Assert(false, "Could not find matching property"); - throw Error.InternalCompilerError(); - } - - ///////////////////////////////////////////////////////////////////////////////// - - private bool TypesAreEqual(Type t1, Type t2) - { - if (t1 == t2) - { - return true; - } - - return t1.IsEquivalentTo(t2); - } #endregion } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ICSharpBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ICSharpBinder.cs index 6976682..84b60ab 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ICSharpBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ICSharpBinder.cs @@ -10,8 +10,6 @@ namespace Microsoft.CSharp.RuntimeBinder internal interface ICSharpBinder { CSharpArgumentInfo GetArgumentInfo(int index); - Type CallingContext { get; } - bool IsChecked { get; } // This is true for any binder that is eligible to take value type receiver // objects as a ref (for mutable operations). Such as calls ("v.M(d)"), @@ -19,10 +17,12 @@ namespace Microsoft.CSharp.RuntimeBinder // are only dispatched dynamically when the receiver is dynamic, and hence boxed. bool IsBinderThatCanHaveRefReceiver { get; } - void PopulateSymbolTableWithName(SymbolTable symbolTable, Type callingType, ArgumentObject[] arguments); + void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments); Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals); + BindingFlag BindingFlags { get; } + string Name { get; } Type ReturnType { get; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs index c15dcf8..44c1848 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinder.cs @@ -14,67 +14,30 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder { - internal sealed class RuntimeBinder + internal readonly struct RuntimeBinder { - #region Singleton Implementation + private static readonly object s_bindLock = new object(); - private static readonly Lazy s_lazyInstance = new Lazy(() => new RuntimeBinder()); + private readonly ExpressionBinder _binder; - public static RuntimeBinder GetInstance() + public RuntimeBinder(Type contextType, bool isChecked = false) { - return s_lazyInstance.Value; - } - - #endregion - - ///////////////////////////////////////////////////////////////////////////////// - // Members - - private SymbolTable _symbolTable; - private CSemanticChecker _semanticChecker; - private SymbolLoader SymbolLoader => _semanticChecker.SymbolLoader; - - private ExprFactory _exprFactory; - private BindingContext _bindingContext; - private ExpressionBinder _binder; - - private readonly object _bindLock = new object(); - - ///////////////////////////////////////////////////////////////////////////////// - // Methods - - #region BookKeeping - private RuntimeBinder() - { - Reset(); - } + AggregateSymbol context; + if (contextType != null) + { + lock (s_bindLock) + { + context = ((AggregateType)SymbolTable.GetCTypeFromType(contextType)).OwningAggregate; + } + } + else + { + context = null; + } - private void Reset() - { - _semanticChecker = new CSemanticChecker(); - - BSYMMGR bsymmgr = _semanticChecker.getBSymmgr(); - - _symbolTable = new SymbolTable( - bsymmgr.GetSymbolTable(), - bsymmgr.GetSymFactory(), - _semanticChecker.GetTypeManager(), - bsymmgr, - _semanticChecker); - _semanticChecker.getPredefTypes().Init(_symbolTable); - _semanticChecker.GetTypeManager().InitTypeFactory(_symbolTable); - SymbolLoader.getPredefinedMembers().RuntimeBinderSymbolTable = _symbolTable; - SymbolLoader.SetSymbolTable(_symbolTable); - - _exprFactory = new ExprFactory(_semanticChecker.SymbolLoader.GetGlobalSymbolContext()); - _bindingContext = new BindingContext(_semanticChecker, _exprFactory); - _binder = new ExpressionBinder(_bindingContext); + _binder = new ExpressionBinder(new BindingContext(context, isChecked)); } - #endregion - - ///////////////////////////////////////////////////////////////////////////////// - public Expression Bind(ICSharpBinder payload, Expression[] parameters, DynamicMetaObject[] args, out DynamicMetaObject deferredBinding) { // The lock is here to protect this instance of the binder from itself @@ -94,7 +57,7 @@ namespace Microsoft.CSharp.RuntimeBinder // ...subsequent calls that were cache hits, i.e., already bound, took less // than 1/1000 sec for the whole 4000 of them. - lock (_bindLock) + lock (s_bindLock) { return BindCore(payload, parameters, args, out deferredBinding); } @@ -108,26 +71,25 @@ namespace Microsoft.CSharp.RuntimeBinder { Debug.Assert(args.Length >= 1); - InitializeCallingContext(payload); ArgumentObject[] arguments = CreateArgumentArray(payload, parameters, args); // On any given bind call, we populate the symbol table with any new // conversions that we find for any of the types specified. We keep a - // running SymbolTable so that we don't have to reflect over types if + // running SymbolTable so that we don't have to reflect over types if // we've seen them already in the table. // // Once we've loaded all the standard conversions into the symbol table, // we can call into the binder to bind the actual call. - payload.PopulateSymbolTableWithName(_symbolTable, arguments[0].Type, arguments); + payload.PopulateSymbolTableWithName(arguments[0].Type, arguments); AddConversionsForArguments(arguments); // When we do any bind, we perform the following steps: // // 1) Create a local variable scope which contains local variable symbols // for each of the parameters, and the instance argument. - // 2) If we have operators, then we don't need to do lookup. Otherwise, - // look for the name and switch on the result - dispatch according to + // 2) If we have operators, then we don't need to do lookup. Otherwise, + // look for the name and switch on the result - dispatch according to // the symbol kind. This results in an Expr being bound that is the expression. // 3) Create the EXPRRETURN which returns the call and wrap it in // an EXPRBOUNDLAMBDA which uses the local variable scope @@ -138,7 +100,7 @@ namespace Microsoft.CSharp.RuntimeBinder // Linq expression tree for the whole thing and return it. // (1) - Create the locals - Scope pScope = _semanticChecker.GetGlobalSymbolFactory().CreateScope(); + Scope pScope = SymFactory.CreateScope(); LocalVariableSymbol[] locals = PopulateLocalScope(payload, pScope, arguments, parameters); // (1.5) - Check to see if we need to defer. @@ -168,7 +130,7 @@ namespace Microsoft.CSharp.RuntimeBinder // (1) InvokeMember deferral. // - // This is the deferral for the d.Foo() scenario where Foo actually binds to a + // This is the deferral for the d.Foo() scenario where Foo actually binds to a // field or property, and not a method group that is invocable. We defer to // the standard GetMember/Invoke pattern. @@ -179,10 +141,10 @@ namespace Microsoft.CSharp.RuntimeBinder MemberLookup mem = new MemberLookup(); Expr callingObject = CreateCallingObjectForCall(callPayload, arguments, locals); - SymWithType swt = _symbolTable.LookupMember( + SymWithType swt = SymbolTable.LookupMember( callPayload.Name, callingObject, - _bindingContext.ContextForMemberLookup, + _binder.Context.ContextForMemberLookup, arity, mem, (callPayload.Flags & CSharpCallFlags.EventHookup) != 0, @@ -211,42 +173,16 @@ namespace Microsoft.CSharp.RuntimeBinder return false; } - private void InitializeCallingContext(ICSharpBinder payload) - { - // Set the context if the payload specifies it. Currently we only use this for calls. - Type t = payload.CallingContext; - BindingContext bindingContext = _bindingContext; - - if (t != null) - { - AggregateSymbol agg = ((AggregateType)_symbolTable.GetCTypeFromType(t)).OwningAggregate; - bindingContext.ContextForMemberLookup = _semanticChecker.GetGlobalSymbolFactory().CreateAggregateDecl(agg, null); - } - else - { - // The binding context lives across invocations! If we don't reset this, then later calls might - // bind in a previous call's context. - bindingContext.ContextForMemberLookup = null; - } - - bindingContext.Checked = payload.IsChecked; - } - - ///////////////////////////////////////////////////////////////////////////////// - - private Expression CreateExpressionTreeFromResult( - Expression[] parameters, - Scope pScope, - Expr pResult) + private static Expression CreateExpressionTreeFromResult(Expression[] parameters, Scope pScope, Expr pResult) { // (3) - Place the result in a return statement and create the ExprBoundLambda. ExprBoundLambda boundLambda = GenerateBoundLambda(pScope, pResult); // (4) - Rewrite the ExprBoundLambda into an expression tree. - ExprBinOp exprTree = ExpressionTreeRewriter.Rewrite(boundLambda, _exprFactory, SymbolLoader); + ExprBinOp exprTree = ExpressionTreeRewriter.Rewrite(boundLambda); // (5) - Create the actual Expression Tree - Expression e = ExpressionTreeCallRewriter.Rewrite(SymbolLoader.GetTypeManager(), exprTree, parameters); + Expression e = ExpressionTreeCallRewriter.Rewrite(exprTree, parameters); return e; } @@ -258,7 +194,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (argInfo.IsByRefOrOut) { // If we have a ref our an out parameter, make the byref type. - // If we have the receiver of a call or invoke that is ref, it must be because of + // If we have the receiver of a call or invoke that is ref, it must be because of // a struct caller. Don't persist the ref for that. if (!(index == 0 && p.IsBinderThatCanHaveRefReceiver)) { @@ -279,8 +215,8 @@ namespace Microsoft.CSharp.RuntimeBinder // a guarantee that we will always be able to find a best accessible type // (which, in the worst case, may be object). - CType actualType = _symbolTable.GetCTypeFromType(t); - CType bestType = _semanticChecker.GetTypeManager().GetBestAccessibleType(_semanticChecker, _bindingContext.ContextForMemberLookup, actualType); + CType actualType = SymbolTable.GetCTypeFromType(t); + CType bestType = TypeManager.GetBestAccessibleType(_binder.Context.ContextForMemberLookup, actualType); t = bestType.AssociatedSystemType; } @@ -312,8 +248,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// internal static void PopulateSymbolTableWithPayloadInformation( - SymbolTable symbolTable, ICSharpInvokeOrInvokeMemberBinder callOrInvoke, Type callingType, - ArgumentObject[] arguments) + ICSharpInvokeOrInvokeMemberBinder callOrInvoke, Type callingType, ArgumentObject[] arguments) { Type type; @@ -329,18 +264,19 @@ namespace Microsoft.CSharp.RuntimeBinder { type = callingType; } - symbolTable.PopulateSymbolTableWithName( + + SymbolTable.PopulateSymbolTableWithName( callOrInvoke.Name, callOrInvoke.TypeArguments, type); // If it looks like we're invoking a get_ or a set_, load the property as well. - // This is because we need COM indexed properties called via method calls to + // This is because we need COM indexed properties called via method calls to // work the same as it used to. if (callOrInvoke.Name.StartsWith("set_", StringComparison.Ordinal) || callOrInvoke.Name.StartsWith("get_", StringComparison.Ordinal)) { - symbolTable.PopulateSymbolTableWithName( + SymbolTable.PopulateSymbolTableWithName( callOrInvoke.Name.Substring(4), //remove prefix callOrInvoke.TypeArguments, type); @@ -349,11 +285,11 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void AddConversionsForArguments(ArgumentObject[] arguments) + private static void AddConversionsForArguments(ArgumentObject[] arguments) { foreach (ArgumentObject arg in arguments) { - _symbolTable.AddConversionsForType(arg.Type); + SymbolTable.AddConversionsForType(arg.Type); } } @@ -363,29 +299,29 @@ namespace Microsoft.CSharp.RuntimeBinder BindCall(payload, CreateCallingObjectForCall(payload, arguments, locals), arguments, locals); ///////////////////////////////////////////////////////////////////////////////// - // We take the ArgumentObjects to verify - if the parameter expression tells us + // We take the ArgumentObjects to verify - if the parameter expression tells us // we have a ref parameter, but the argument object tells us we're not passed by ref, // then it means it was a ref that the compiler had to insert. This is used when - // we have a call off of a struct for example. If thats the case, don't treat the + // we have a call off of a struct for example. If thats the case, don't treat the // local as a ref type. - private LocalVariableSymbol[] PopulateLocalScope( + private static LocalVariableSymbol[] PopulateLocalScope( ICSharpBinder payload, Scope pScope, ArgumentObject[] arguments, Expression[] parameterExpressions) { - // We use the compile time types for the local variables, and then + // We use the compile time types for the local variables, and then // cast them to the runtime types for the expression tree. LocalVariableSymbol[] locals = new LocalVariableSymbol[parameterExpressions.Length]; for (int i = 0; i < parameterExpressions.Length; i++) { Expression parameter = parameterExpressions[i]; - CType type = _symbolTable.GetCTypeFromType(parameter.Type); + CType type = SymbolTable.GetCTypeFromType(parameter.Type); // Make sure we're not setting ref for the receiver of a call - the argument - // will be marked as ref if we're calling off a struct, but we don't want + // will be marked as ref if we're calling off a struct, but we don't want // to persist that in our system. // If we're the first param of a call or invoke, and we're ref, it must be // because of structs. Don't persist the parameter modifier type. @@ -398,13 +334,12 @@ namespace Microsoft.CSharp.RuntimeBinder CSharpArgumentInfo info = arguments[i].Info; if (info.IsByRefOrOut) { - type = _semanticChecker.GetTypeManager().GetParameterModifier(type, info.IsOut); + type = TypeManager.GetParameterModifier(type, info.IsOut); } } } LocalVariableSymbol local = - _semanticChecker.GetGlobalSymbolFactory() - .CreateLocalVar(NameManager.Add("p" + i), pScope, type); + SymFactory.CreateLocalVar(NameManager.Add("p" + i), pScope, type); locals[i] = local; } @@ -413,14 +348,12 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private ExprBoundLambda GenerateBoundLambda( - Scope pScope, - Expr call) + private static ExprBoundLambda GenerateBoundLambda(Scope pScope, Expr call) { // We don't actually need the real delegate type here - we just need SOME delegate type. // This is because we never attempt any conversions on the lambda itself. - AggregateType delegateType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_FUNC); - return _exprFactory.CreateAnonymousMethod(delegateType, pScope, call); + AggregateType delegateType = SymbolLoader.GetPredefindType(PredefinedType.PT_FUNC); + return ExprFactory.CreateAnonymousMethod(delegateType, pScope, call); } #region ExprCreation @@ -437,16 +370,15 @@ namespace Microsoft.CSharp.RuntimeBinder // IsOut to be true. So do that logic here rather than create a ref type to then // throw away. Debug.Assert(type.IsByRef); - ctype = _semanticChecker.GetTypeManager() - .GetParameterModifier(_symbolTable.GetCTypeFromType(type.GetElementType()), true); + ctype = TypeManager.GetParameterModifier(SymbolTable.GetCTypeFromType(type.GetElementType()), true); } else { - ctype = _symbolTable.GetCTypeFromType(type); + ctype = SymbolTable.GetCTypeFromType(type); } // If we can convert, do that. If not, cast it. - ExprLocal exprLocal = _exprFactory.CreateLocal(local); + ExprLocal exprLocal = ExprFactory.CreateLocal(local); Expr result = _binder.tryConvert(exprLocal, ctype) ?? _binder.mustCast(exprLocal, ctype); result.Flags |= EXPRFLAG.EXF_LVALUE; return result; @@ -478,7 +410,7 @@ namespace Microsoft.CSharp.RuntimeBinder else { // Lists are right-heavy. - _exprFactory.AppendItemToList(arg, ref args, ref last); + ExprFactory.AppendItemToList(arg, ref args, ref last); } } } @@ -496,16 +428,16 @@ namespace Microsoft.CSharp.RuntimeBinder { if (argument.Info.UseCompileTimeType) { - arg = _exprFactory.CreateConstant(_symbolTable.GetCTypeFromType(argument.Type), default(ConstVal)); + arg = ExprFactory.CreateConstant(SymbolTable.GetCTypeFromType(argument.Type), default(ConstVal)); } else { - arg = _exprFactory.CreateNull(); + arg = ExprFactory.CreateNull(); } } else { - arg = _exprFactory.CreateConstant(_symbolTable.GetCTypeFromType(argument.Type), ConstVal.Get(argument.Value)); + arg = ExprFactory.CreateConstant(SymbolTable.GetCTypeFromType(argument.Type), ConstVal.Get(argument.Value)); } } else @@ -515,7 +447,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (!argument.Info.UseCompileTimeType && argument.Value == null) { - arg = _exprFactory.CreateNull(); + arg = ExprFactory.CreateNull(); } else { @@ -527,7 +459,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (argument.Info.NamedArgument) { Debug.Assert(argument.Info.Name != null); - arg = _exprFactory.CreateNamedArgumentSpecification(NameManager.Add(argument.Info.Name), arg); + arg = ExprFactory.CreateNamedArgumentSpecification(NameManager.Add(argument.Info.Name), arg); } // If we have an object that was "dynamic" at compile time, we need @@ -548,7 +480,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (!argument.Info.UseCompileTimeType && argument.Value != null) { arg.RuntimeObject = argument.Value; - arg.RuntimeObjectActualType = _symbolTable.GetCTypeFromType(argument.Value.GetType()); + arg.RuntimeObjectActualType = SymbolTable.GetCTypeFromType(argument.Value.GetType()); } return arg; @@ -556,7 +488,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private ExprMemberGroup CreateMemberGroupEXPR( + private static ExprMemberGroup CreateMemberGroupExpr( string Name, Type[] typeArguments, Expr callingObject, @@ -568,7 +500,7 @@ namespace Microsoft.CSharp.RuntimeBinder CType callingObjectType = callingObject.Type; if (callingObjectType is ArrayType) { - callingType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY); + callingType = SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY); } else if (callingObjectType is NullableType callingNub) { @@ -611,7 +543,7 @@ namespace Microsoft.CSharp.RuntimeBinder bool bIsConstructor = name == NameManager.GetPredefinedName(PredefinedName.PN_CTOR); foreach(AggregateType t in callingType.TypeHierarchy) { - if (_symbolTable.AggregateContainsMethod(t.OwningAggregate, Name, mask) && distinctCallingTypes.Add(t)) + if (SymbolTable.AggregateContainsMethod(t.OwningAggregate, Name, mask) && distinctCallingTypes.Add(t)) { callingTypes.Add(t); } @@ -623,13 +555,13 @@ namespace Microsoft.CSharp.RuntimeBinder } } - // If this is a WinRT type we have to add all collection interfaces that have this method + // If this is a WinRT type we have to add all collection interfaces that have this method // as well so that overload resolution can find them. if (callingType.IsWindowsRuntimeType) { - foreach (AggregateType t in callingType.GetWinRTCollectionIfacesAll(SymbolLoader).Items) + foreach (AggregateType t in callingType.WinRTCollectionIfacesAll.Items) { - if (_symbolTable.AggregateContainsMethod(t.OwningAggregate, Name, mask) && distinctCallingTypes.Add(t)) + if (SymbolTable.AggregateContainsMethod(t.OwningAggregate, Name, mask) && distinctCallingTypes.Add(t)) { callingTypes.Add(t); } @@ -655,16 +587,13 @@ namespace Microsoft.CSharp.RuntimeBinder flags |= EXPRFLAG.EXF_INDEXER; } - TypeArray typeArgumentsAsTypeArray = BSYMMGR.EmptyTypeArray(); - if (typeArguments != null && typeArguments.Length > 0) - { - typeArgumentsAsTypeArray = _semanticChecker.getBSymmgr().AllocParams( - _symbolTable.GetCTypeArrayFromTypes(typeArguments)); - } - ExprMemberGroup memgroup = _exprFactory.CreateMemGroup(// Tree - flags, name, typeArgumentsAsTypeArray, kind, callingType, null, null, new CMemberLookupResults( - _semanticChecker.getBSymmgr().AllocParams(callingTypes.Count, callingTypes.ToArray()), - name)); + TypeArray typeArgumentsAsTypeArray = typeArguments?.Length > 0 + ? TypeArray.Allocate(SymbolTable.GetCTypeArrayFromTypes(typeArguments)) + : TypeArray.Empty; + + ExprMemberGroup memgroup = ExprFactory.CreateMemGroup( // Tree + flags, name, typeArgumentsAsTypeArray, kind, callingType, null, + new CMemberLookupResults(TypeArray.Allocate(callingTypes.ToArray()), name)); if (callingObject is ExprClass) { memgroup.OptionalLHS = callingObject; @@ -689,7 +618,7 @@ namespace Microsoft.CSharp.RuntimeBinder PropertySymbol property = swt.Prop(); AggregateType propertyType = swt.GetType(); PropWithType pwt = new PropWithType(property, propertyType); - ExprMemberGroup pMemGroup = CreateMemberGroupEXPR(property.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol); + ExprMemberGroup pMemGroup = CreateMemberGroupExpr(property.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol); return _binder.BindToProperty(// For a static property instance, don't set the object. callingObject is ExprClass ? null : callingObject, pwt, flags, null, pMemGroup); @@ -700,7 +629,7 @@ namespace Microsoft.CSharp.RuntimeBinder private ExprWithArgs CreateIndexer(SymWithType swt, Expr callingObject, Expr arguments, BindingFlag bindFlags) { IndexerSymbol index = swt.Sym as IndexerSymbol; - ExprMemberGroup memgroup = CreateMemberGroupEXPR(index.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol); + ExprMemberGroup memgroup = CreateMemberGroupExpr(index.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol); ExprWithArgs result = _binder.BindMethodGroupToArguments(bindFlags, memgroup, arguments); ReorderArgumentsForNamedAndOptional(callingObject, result); return result; @@ -751,7 +680,7 @@ namespace Microsoft.CSharp.RuntimeBinder Type t = arguments[0].Value as Type; Debug.Assert(t != null); // Would have thrown in PopulateSymbolTableWithPayloadInformation already - callingObject = _exprFactory.CreateClass(_symbolTable.GetCTypeFromType(t)); + callingObject = ExprFactory.CreateClass(SymbolTable.GetCTypeFromType(t)); } else { @@ -763,7 +692,7 @@ namespace Microsoft.CSharp.RuntimeBinder callingObject = _binder.mustConvert( CreateArgumentEXPR(arguments[0], locals[0]), - _symbolTable.GetCTypeFromType(arguments[0].Type)); + SymbolTable.GetCTypeFromType(arguments[0].Type)); if (arguments[0].Type.IsValueType && callingObject is ExprCast) { @@ -790,10 +719,10 @@ namespace Microsoft.CSharp.RuntimeBinder int arity = payload.TypeArguments?.Length ?? 0; MemberLookup mem = new MemberLookup(); - SymWithType swt = _symbolTable.LookupMember( + SymWithType swt = SymbolTable.LookupMember( payload.Name, callingObject, - _bindingContext.ContextForMemberLookup, + _binder.Context.ContextForMemberLookup, arity, mem, (payload.Flags & CSharpCallFlags.EventHookup) != 0, @@ -819,11 +748,11 @@ namespace Microsoft.CSharp.RuntimeBinder // // Our caller takes care of the rest. - // First we need to check the sym that we got back. If we got back a static + // First we need to check the sym that we got back. If we got back a static // method, then we may be in the situation where the user called the method // via a simple name call through the phantom overload. If thats the case, // then we want to sub in a type instead of the object. - ExprMemberGroup memGroup = CreateMemberGroupEXPR(payload.Name, payload.TypeArguments, callingObject, swt.Sym.getKind()); + ExprMemberGroup memGroup = CreateMemberGroupExpr(payload.Name, payload.TypeArguments, callingObject, swt.Sym.getKind()); if ((payload.Flags & CSharpCallFlags.SimpleNameCall) != 0) { callingObject.Flags |= EXPRFLAG.EXF_SIMPLENAME; @@ -832,10 +761,10 @@ namespace Microsoft.CSharp.RuntimeBinder if ((payload.Flags & CSharpCallFlags.EventHookup) != 0) { mem = new MemberLookup(); - SymWithType swtEvent = _symbolTable.LookupMember( + SymWithType swtEvent = SymbolTable.LookupMember( payload.Name.Split('_')[1], callingObject, - _bindingContext.ContextForMemberLookup, + _binder.Context.ContextForMemberLookup, arity, mem, (payload.Flags & CSharpCallFlags.EventHookup) != 0, @@ -855,7 +784,7 @@ namespace Microsoft.CSharp.RuntimeBinder eventCType = swtEvent.Event().type; } - Type eventType = SymbolLoader.GetTypeManager().SubstType(eventCType, swtEvent.Ats).AssociatedSystemType; + Type eventType = TypeManager.SubstType(eventCType, swtEvent.Ats).AssociatedSystemType; if (eventType != null) { @@ -904,11 +833,11 @@ namespace Microsoft.CSharp.RuntimeBinder // Get new Action(x.remove_foo) MethPropWithInst removemwi = new MethPropWithInst(ewt.Event().methRemove, ewt.Ats); - ExprMemberGroup removeMethGrp = _exprFactory.CreateMemGroup(callingObject, removemwi); + ExprMemberGroup removeMethGrp = ExprFactory.CreateMemGroup(callingObject, removemwi); removeMethGrp.Flags &= ~EXPRFLAG.EXF_USERCALLABLE; Type eventRegistrationTokenType = SymbolTable.EventRegistrationTokenType; Type actionType = Expression.GetActionType(eventRegistrationTokenType); - Expr removeMethArg = _binder.mustConvert(removeMethGrp, _symbolTable.GetCTypeFromType(actionType)); + Expr removeMethArg = _binder.mustConvert(removeMethGrp, SymbolTable.GetCTypeFromType(actionType)); // The value Expr delegateVal = CreateArgumentEXPR(arguments[1], locals[1]); @@ -919,25 +848,25 @@ namespace Microsoft.CSharp.RuntimeBinder { // Get new Func(x.add_foo) MethPropWithInst addmwi = new MethPropWithInst(ewt.Event().methAdd, ewt.Ats); - ExprMemberGroup addMethGrp = _exprFactory.CreateMemGroup(callingObject, addmwi); + ExprMemberGroup addMethGrp = ExprFactory.CreateMemGroup(callingObject, addmwi); addMethGrp.Flags &= ~EXPRFLAG.EXF_USERCALLABLE; Type funcType = Expression.GetFuncType(evtType, eventRegistrationTokenType); - Expr addMethArg = _binder.mustConvert(addMethGrp, _symbolTable.GetCTypeFromType(funcType)); + Expr addMethArg = _binder.mustConvert(addMethGrp, SymbolTable.GetCTypeFromType(funcType)); - args = _exprFactory.CreateList(addMethArg, removeMethArg, delegateVal); + args = ExprFactory.CreateList(addMethArg, removeMethArg, delegateVal); methodName = NameManager.GetPredefinedName(PredefinedName.PN_ADDEVENTHANDLER).Text; } else { - args = _exprFactory.CreateList(removeMethArg, delegateVal); + args = ExprFactory.CreateList(removeMethArg, delegateVal); methodName = NameManager.GetPredefinedName(PredefinedName.PN_REMOVEEVENTHANDLER).Text; } // WindowsRuntimeMarshal.Add\RemoveEventHandler(...) Type windowsRuntimeMarshalType = SymbolTable.WindowsRuntimeMarshalType; - _symbolTable.PopulateSymbolTableWithName(methodName, new List { evtType }, windowsRuntimeMarshalType); - ExprClass marshalClass = _exprFactory.CreateClass(_symbolTable.GetCTypeFromType(windowsRuntimeMarshalType)); - ExprMemberGroup addEventGrp = CreateMemberGroupEXPR(methodName, new [] { evtType }, marshalClass, SYMKIND.SK_MethodSymbol); + SymbolTable.PopulateSymbolTableWithName(methodName, new List { evtType }, windowsRuntimeMarshalType); + ExprClass marshalClass = ExprFactory.CreateClass(SymbolTable.GetCTypeFromType(windowsRuntimeMarshalType)); + ExprMemberGroup addEventGrp = CreateMemberGroupExpr(methodName, new [] { evtType }, marshalClass, SYMKIND.SK_MethodSymbol); return _binder.BindMethodGroupToArguments( BindingFlag.BIND_RVALUEREQUIRED | BindingFlag.BIND_STMTEXPRONLY, addEventGrp, @@ -983,49 +912,33 @@ namespace Microsoft.CSharp.RuntimeBinder { carg = ExpressionBinder.CountArguments(arguments) }; - _binder.FillInArgInfoFromArgList(argInfo, arguments); + ExpressionBinder.FillInArgInfoFromArgList(argInfo, arguments); // We need to substitute type parameters BEFORE getting the most derived one because - // we're binding against the base method, and the derived method may change the - // generic arguments. - TypeArray parameters = SymbolLoader.GetTypeManager().SubstTypeArray(methprop.Params, type, typeArgs); - methprop = ExpressionBinder.GroupToArgsBinder.FindMostDerivedMethod(SymbolLoader, methprop, callingObject.Type); + // we're binding against the base method, and the derived method may change the + // generic arguments. + TypeArray parameters = TypeManager.SubstTypeArray(methprop.Params, type, typeArgs); + methprop = ExpressionBinder.GroupToArgsBinder.FindMostDerivedMethod(methprop, callingObject.Type); ExpressionBinder.GroupToArgsBinder.ReOrderArgsForNamedArguments( - methprop, - parameters, - type, - memgroup, - argInfo, - _semanticChecker.GetTypeManager(), - _exprFactory, - SymbolLoader); - { - Expr pList = null; - - // We reordered, so make a new list of them and set them on the constructor. - // Go backwards cause lists are right-flushed. - // Also perform the conversions to the right types. - for (int i = argInfo.carg - 1; i >= 0; i--) - { - Expr pArg = argInfo.prgexpr[i]; + methprop, parameters, type, memgroup, argInfo); + Expr pList = null; - // Strip the name-ness away, since we don't need it. - pArg = StripNamedArgument(pArg); + // We reordered, so make a new list of them and set them on the constructor. + // Go backwards cause lists are right-flushed. + // Also perform the conversions to the right types. + for (int i = argInfo.carg - 1; i >= 0; i--) + { + Expr pArg = argInfo.prgexpr[i]; - // Perform the correct conversion. - pArg = _binder.tryConvert(pArg, parameters[i]); - if (pList == null) - { - pList = pArg; - } - else - { - pList = _exprFactory.CreateList(pArg, pList); - } - } + // Strip the name-ness away, since we don't need it. + pArg = StripNamedArgument(pArg); - result.OptionalArguments = pList; + // Perform the correct conversion. + pArg = _binder.tryConvert(pArg, parameters[i]); + pList = pList == null ? pArg : ExprFactory.CreateList(pArg, pList); } + + result.OptionalArguments = pList; } private Expr StripNamedArgument(Expr pArg) @@ -1092,20 +1005,15 @@ namespace Microsoft.CSharp.RuntimeBinder result = _binder.BindStandardUnaryOperator(OperatorKind.OP_LOGNOT, result); } - if (result == null) - { - result = _binder.bindUDUnop(op == OperatorKind.OP_TRUE ? ExpressionKind.True : ExpressionKind.False, arg1); - } + return result + ?? _binder.bindUDUnop(op == OperatorKind.OP_TRUE ? ExpressionKind.True : ExpressionKind.False, arg1) + // If the result is STILL null, then that means theres no implicit conversion to bool, + // and no user-defined operators for true and false. Just do a must convert to report + // the error. + ?? _binder.mustConvert(arg1, SymbolLoader.GetPredefindType(PredefinedType.PT_BOOL)); - // If the result is STILL null, then that means theres no implicit conversion to bool, - // and no user-defined operators for true and false. Just do a must convert to report - // the error. - if (result == null) - { - result = _binder.mustConvert(arg1, SymbolLoader.GetPredefindType(PredefinedType.PT_BOOL)); - } - return result; } + return _binder.BindStandardUnaryOperator(op, arg1); } #endregion @@ -1244,7 +1152,7 @@ namespace Microsoft.CSharp.RuntimeBinder { // If our argument is a static type, then we're calling a static property. Expr callingObject = argument.Info.IsStaticType ? - _exprFactory.CreateClass(_symbolTable.GetCTypeFromType(argument.Value as Type)) : + ExprFactory.CreateClass(SymbolTable.GetCTypeFromType(argument.Value as Type)) : CreateLocal(argument.Type, argument.Info.IsOut, local); if (!argument.Info.UseCompileTimeType && argument.Value == null) @@ -1262,7 +1170,7 @@ namespace Microsoft.CSharp.RuntimeBinder BindingFlag bindFlags = payload.BindingFlags; MemberLookup mem = new MemberLookup(); - SymWithType swt = _symbolTable.LookupMember(name, callingObject, _bindingContext.ContextForMemberLookup, 0, mem, false, false); + SymWithType swt = SymbolTable.LookupMember(name, callingObject, _binder.Context.ContextForMemberLookup, 0, mem, false, false); if (swt == null) { if (optionalIndexerArguments != null) @@ -1275,9 +1183,9 @@ namespace Microsoft.CSharp.RuntimeBinder { if (type.IsArray && type.GetArrayRank() != numIndexArguments) { - throw _semanticChecker.ErrorContext.Error(ErrorCode.ERR_BadIndexCount, type.GetArrayRank()); + throw ErrorHandling.Error(ErrorCode.ERR_BadIndexCount, type.GetArrayRank()); } - + Debug.Assert(callingObject.Type is ArrayType); return CreateArray(callingObject, optionalIndexerArguments); } @@ -1328,10 +1236,10 @@ namespace Microsoft.CSharp.RuntimeBinder Debug.Assert(arguments.Length == 1); // Load the conversions on the target. - _symbolTable.AddConversionsForType(returnType); + SymbolTable.AddConversionsForType(returnType); Expr argument = CreateArgumentEXPR(arguments[0], locals[0]); - CType destinationType = _symbolTable.GetCTypeFromType(returnType); + CType destinationType = SymbolTable.GetCTypeFromType(returnType); if (bIsArrayCreationConversion) { @@ -1362,10 +1270,10 @@ namespace Microsoft.CSharp.RuntimeBinder Debug.Assert(arguments.Length == 1); // Load the conversions on the target. - _symbolTable.AddConversionsForType(returnType); + SymbolTable.AddConversionsForType(returnType); Expr argument = CreateArgumentEXPR(arguments[0], locals[0]); - CType destinationType = _symbolTable.GetCTypeFromType(returnType); + CType destinationType = SymbolTable.GetCTypeFromType(returnType); return _binder.mustCast(argument, destinationType); } @@ -1402,7 +1310,8 @@ namespace Microsoft.CSharp.RuntimeBinder indexerArguments = null; bIsCompound = (payload as CSharpSetMemberBinder).IsCompoundAssignment; } - _symbolTable.PopulateSymbolTableWithName(name, null, arguments[0].Type); + + SymbolTable.PopulateSymbolTableWithName(name, null, arguments[0].Type); Expr lhs = BindProperty(payload, arguments[0], locals[0], indexerArguments); int indexOfLast = arguments.Length - 1; @@ -1419,7 +1328,7 @@ namespace Microsoft.CSharp.RuntimeBinder ArgumentObject[] arguments, LocalVariableSymbol[] locals) { - // The IsEvent binder will never be called without an instance object. This + // The IsEvent binder will never be called without an instance object. This // is because the compiler only gen's this code for dynamic dots. Expr callingObject = CreateLocal(arguments[0].Type, false, locals[0]); @@ -1432,10 +1341,10 @@ namespace Microsoft.CSharp.RuntimeBinder throw Error.NullReferenceOnMemberException(); } - SymWithType swt = _symbolTable.LookupMember( + SymWithType swt = SymbolTable.LookupMember( binder.Name, callingObject, - _bindingContext.ContextForMemberLookup, + _binder.Context.ContextForMemberLookup, 0, mem, false, @@ -1459,7 +1368,7 @@ namespace Microsoft.CSharp.RuntimeBinder } } - return _exprFactory.CreateConstant(boolType, ConstVal.Get(result)); + return ExprFactory.CreateConstant(boolType, ConstVal.Get(result)); } #endregion } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpArgInfo.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpArgInfo.cs index 420e4df..ce1b858 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpArgInfo.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpArgInfo.cs @@ -7,7 +7,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { private sealed class BinOpArgInfo { diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpSig.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpSig.cs index db41f04..6a4efe0 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpSig.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BinOpSig.cs @@ -7,7 +7,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { private class BinOpSig { @@ -85,8 +85,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics this.grfos = bos.grfos; this.fnkind = bos.fnkind; - _type1 = pt1 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt1) : null; - _type2 = pt2 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt2) : null; + _type1 = pt1 != PredefinedType.PT_UNDEFINEDINDEX ? GetPredefindType(pt1) : null; + _type2 = pt2 != PredefinedType.PT_UNDEFINEDINDEX ? GetPredefindType(pt2) : null; _grflt = LiftFlags.None; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs index 787b61c..de077e9 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs @@ -9,7 +9,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { //////////////////////////////////////////////////////////////////////////////// // This table is used to implement the last set of 'better' conversion rules @@ -38,7 +38,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics new byte[] /* OBJECT*/ {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} }; - private BetterType WhichMethodIsBetterTieBreaker( + private static BetterType WhichMethodIsBetterTieBreaker( CandidateFunctionMember node1, CandidateFunctionMember node2, CType pTypeThrough, @@ -83,7 +83,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } // See if one's parameter types (un-instantiated) are more specific. - BetterType nT = GetGlobalSymbols().CompareTypes( + BetterType nT = CompareTypes( RearrangeNamedArguments(mpwi1.MethProp().Params, mpwi1, pTypeThrough, args), RearrangeNamedArguments(mpwi2.MethProp().Params, mpwi2, pTypeThrough, args)); if (nT == BetterType.Left || nT == BetterType.Right) @@ -101,6 +101,79 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return BetterType.Neither; } + private static BetterType CompareTypes(TypeArray ta1, TypeArray ta2) + { + if (ta1 == ta2) + { + return BetterType.Same; + } + + if (ta1.Count != ta2.Count) + { + // The one with more parameters is more specific. + return ta1.Count > ta2.Count ? BetterType.Left : BetterType.Right; + } + + BetterType nTot = BetterType.Neither; + + for (int i = 0; i < ta1.Count; i++) + { + CType type1 = ta1[i]; + CType type2 = ta2[i]; + BetterType nParam = BetterType.Neither; + +LAgain: + if (type1.TypeKind != type2.TypeKind) + { + if (type1 is TypeParameterType) + { + nParam = BetterType.Right; + } + else if (type2 is TypeParameterType) + { + nParam = BetterType.Left; + } + } + else + { + switch (type1.TypeKind) + { + default: + Debug.Assert(false, "Bad kind in CompareTypes"); + break; + case TypeKind.TK_TypeParameterType: + break; + + case TypeKind.TK_PointerType: + case TypeKind.TK_ParameterModifierType: + case TypeKind.TK_ArrayType: + case TypeKind.TK_NullableType: + type1 = type1.BaseOrParameterOrElementType; + type2 = type2.BaseOrParameterOrElementType; + goto LAgain; + + case TypeKind.TK_AggregateType: + nParam = CompareTypes(((AggregateType)type1).TypeArgsAll, ((AggregateType)type2).TypeArgsAll); + break; + } + } + + if (nParam == BetterType.Right || nParam == BetterType.Left) + { + if (nTot == BetterType.Same || nTot == BetterType.Neither) + { + nTot = nParam; + } + else if (nParam != nTot) + { + return BetterType.Neither; + } + } + } + + return nTot; + } + //////////////////////////////////////////////////////////////////////////////// // Find the index of a name on a list. @@ -126,8 +199,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // By rearranging the arguments as such we make sure that any specified named arguments appear in the same position for both // methods and we also maintain the relative order of the other parameters (the type long appears after int in the above example) - private TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi, - CType pTypeThrough, ArgInfos args) + private static TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi, CType pTypeThrough, ArgInfos args) { #if DEBUG // We never have a named argument that is in a position in the argument @@ -147,7 +219,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType type = pTypeThrough != null ? pTypeThrough : mpwi.GetType(); CType[] typeList = new CType[pta.Count]; - MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mpwi.MethProp(), type); + MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(mpwi.MethProp(), type); // We initialize the new type array with the parameters for the method. for (int iParam = 0; iParam < pta.Count; iParam++) @@ -179,7 +251,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - return GetSymbolLoader().getBSymmgr().AllocParams(pta.Count, typeList); + return TypeArray.Allocate(typeList); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BindingContext.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BindingContext.cs index 18783d2..cfbdee4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BindingContext.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/BindingContext.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Diagnostics; - namespace Microsoft.CSharp.RuntimeBinder.Semantics { // ---------------------------------------------------------------------------- @@ -11,36 +9,23 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // consumed by the StatementBinder. // ---------------------------------------------------------------------------- - internal sealed class BindingContext + internal readonly struct BindingContext { - public BindingContext(CSemanticChecker semanticChecker, ExprFactory exprFactory) + public BindingContext(AggregateSymbol context, bool isChecked) { - Debug.Assert(semanticChecker != null); - ExprFactory = exprFactory; - SemanticChecker = semanticChecker; - SymbolLoader = semanticChecker.SymbolLoader; + ContextForMemberLookup = context; + Checked = isChecked; } public BindingContext(BindingContext parent) - : this(parent.SemanticChecker, parent.ExprFactory) { // We copy the context object, but leave checking false. ContextForMemberLookup = parent.ContextForMemberLookup; + Checked = false; } - //The SymbolLoader can be retrieved from SemanticChecker, - //but that is a virtual call that is showing up on the profiler. Retrieve - //the SymbolLoader once at construction and return a cached copy. - - // PERFORMANCE: Is this cache still necessary? - public SymbolLoader SymbolLoader { get; } - - public AggregateDeclaration ContextForMemberLookup { get; set; } - - public CSemanticChecker SemanticChecker { get; } - - public ExprFactory ExprFactory { get; } + public AggregateSymbol ContextForMemberLookup { get; } - public bool Checked { get; set; } + public bool Checked { get; } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs index 2f357e2..4d7771f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs @@ -40,7 +40,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Neither = 3, } - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { private delegate bool ConversionFunc( Expr pSourceExpr, @@ -351,8 +351,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (BindImplicitConversion(expr, expr.Type, dest, out Expr exprResult, flags)) { // Conversion works. - checkUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops - checkUnsafe(dest); // added to the binder so we don't bind to pointer ops + CheckUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops + CheckUnsafe(dest); // added to the binder so we don't bind to pointer ops return exprResult; } @@ -371,18 +371,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Failed because value was out of range. Report nifty error message. string value = constant.Int64Value.ToString(CultureInfo.InvariantCulture); - throw ErrorContext.Error(ErrorCode.ERR_ConstOutOfRange, value, dest); + throw ErrorHandling.Error(ErrorCode.ERR_ConstOutOfRange, value, dest); } } if (expr.Type is NullType && dest.FundamentalType != FUNDTYPE.FT_REF) { - throw ErrorContext.Error(ErrorCode.ERR_ValueCantBeNull, dest); + throw ErrorHandling.Error(ErrorCode.ERR_ValueCantBeNull, dest); } // canCast => can't convert, but explicit exists and can be specified by the user (no anonymous types). // !canCast => Generic "can't convert" error. - throw ErrorContext.Error(canCast(expr.Type, dest, flags) ? ErrorCode.ERR_NoImplicitConvCast : ErrorCode.ERR_NoImplicitConv, new ErrArg(expr.Type, ErrArgFlags.Unique), new ErrArg(dest, ErrArgFlags.Unique)); + throw ErrorHandling.Error(canCast(expr.Type, dest, flags) ? ErrorCode.ERR_NoImplicitConvCast : ErrorCode.ERR_NoImplicitConv, new ErrArg(expr.Type, ErrArgFlags.Unique), new ErrArg(dest, ErrArgFlags.Unique)); } // performs an implicit conversion if its possible. otherwise returns null. flags is an optional parameter. @@ -400,8 +400,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (BindImplicitConversion(expr, expr.Type, dest, out Expr exprResult, flags)) { - checkUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops - checkUnsafe(dest); // added to the binder so we don't bind to pointer ops + CheckUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops + CheckUnsafe(dest); // added to the binder so we don't bind to pointer ops // Conversion works. return exprResult; } @@ -425,12 +425,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(!(expr is ExprMemberGroup)); Debug.Assert(dest != null); - SemanticChecker.CheckForStaticClass(dest); + CSemanticChecker.CheckForStaticClass(dest); if (BindExplicitConversion(expr, expr.Type, dest, out Expr exprResult, flags)) { // Conversion works. - checkUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops - checkUnsafe(dest); // added to the binder so we don't bind to pointer ops + CheckUnsafe(expr.Type); // added to the binder so we don't bind to pointer ops + CheckUnsafe(dest); // added to the binder so we don't bind to pointer ops return exprResult; } @@ -446,7 +446,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // We have a constant decimal that is out of range of the destination type. // In both checked and unchecked contexts we issue an error. No need to recheck conversion in unchecked context. // Decimal is a SimpleType represented in a FT_STRUCT - throw ErrorContext.Error( + throw ErrorHandling.Error( ErrorCode.ERR_ConstOutOfRange, ((ExprConstant)exprConst).Val.DecimalVal.ToString(CultureInfo.InvariantCulture), dest); } @@ -454,7 +454,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (Context.Checked) { // check if we failed because we are in checked mode... - if (!canExplicitConversionBeBoundInUncheckedContext(expr, expr.Type, dest, flags | CONVERTTYPE.NOUDC)) + if (!CanExplicitConversionBeBoundInUncheckedContext(expr, expr.Type, dest, flags | CONVERTTYPE.NOUDC)) { throw CantConvert(expr, dest); } @@ -483,34 +483,31 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics break; } - throw ErrorContext.Error(ErrorCode.ERR_ConstOutOfRangeChecked, value, dest); + throw ErrorHandling.Error(ErrorCode.ERR_ConstOutOfRangeChecked, value, dest); } } if (expr.Type is NullType && dest.FundamentalType != FUNDTYPE.FT_REF) { - throw ErrorContext.Error(ErrorCode.ERR_ValueCantBeNull, dest); + throw ErrorHandling.Error(ErrorCode.ERR_ValueCantBeNull, dest); } throw CantConvert(expr, dest); } - private RuntimeBinderException CantConvert(Expr expr, CType dest) + private static RuntimeBinderException CantConvert(Expr expr, CType dest) { // Generic "can't convert" error. Debug.Assert(expr.Type != null); - return ErrorContext.Error(ErrorCode.ERR_NoExplicitConv, new ErrArg(expr.Type, ErrArgFlags.Unique), new ErrArg(dest, ErrArgFlags.Unique)); + return ErrorHandling.Error(ErrorCode.ERR_NoExplicitConv, new ErrArg(expr.Type, ErrArgFlags.Unique), new ErrArg(dest, ErrArgFlags.Unique)); } public Expr mustCast(Expr expr, CType dest) => mustCast(expr, dest, 0); public Expr mustCast(Expr expr, CType dest, CONVERTTYPE flags) => mustCastCore(expr, dest, flags); - private Expr mustCastInUncheckedContext(Expr expr, CType dest, CONVERTTYPE flags) - { - BindingContext ctx = new BindingContext(Context); - return (new ExpressionBinder(ctx)).mustCast(expr, dest, flags); - } + private Expr MustCastInUncheckedContext(Expr expr, CType dest, CONVERTTYPE flags) => + new ExpressionBinder(new BindingContext(Context)).mustCast(expr, dest, flags); // returns true if an explicit conversion exists from source type to dest type. flags is an optional parameter. private bool canCast(CType src, CType dest, CONVERTTYPE flags) => BindExplicitConversion(null, src, dest, flags); @@ -630,7 +627,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics bool fIntPtrOverride2 = false; // Get the list of operators from the source. - if (typeSrcBase is AggregateType atSrcBase && atSrcBase.OwningAggregate.HasConversion(GetSymbolLoader())) + if (typeSrcBase is AggregateType atSrcBase && atSrcBase.OwningAggregate.HasConversion()) { rgats[cats++] = atSrcBase; fIntPtrOverride2 = atSrcBase.IsPredefType(PredefinedType.PT_INTPTR) || atSrcBase.IsPredefType(PredefinedType.PT_UINTPTR); @@ -639,7 +636,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Get the list of operators from the destination. if (typeDstBase is AggregateType atDstBase) { - if (atDstBase.OwningAggregate.HasConversion(GetSymbolLoader())) + if (atDstBase.OwningAggregate.HasConversion()) { rgats[cats++] = atDstBase; } @@ -672,7 +669,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // In the first pass if we find types that are non-comparable, keep one of the types and keep going. for (int iats = 0; iats < cats; iats++) { - for (AggregateType atsCur = rgats[iats]; atsCur != null && atsCur.OwningAggregate.HasConversion(GetSymbolLoader()); atsCur = atsCur.BaseClass) + for (AggregateType atsCur = rgats[iats]; atsCur != null && atsCur.OwningAggregate.HasConversion(); atsCur = atsCur.BaseClass) { AggregateSymbol aggCur = atsCur.OwningAggregate; @@ -699,8 +696,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics continue; // Get the substituted src and dst types. - typeFrom = GetTypes().SubstType(convCur.Params[0], atsCur); - typeTo = GetTypes().SubstType(convCur.RetType, atsCur); + typeFrom = TypeManager.SubstType(convCur.Params[0], atsCur); + typeTo = TypeManager.SubstType(convCur.RetType, atsCur); bool fNeedImplicit = fImplicitOnly; @@ -731,9 +728,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Lift the conversion if needed. if (fLiftSrc && (fDstHasNull || !fNeedImplicit) && typeFrom.IsNonNullableValueType) - typeFrom = GetTypes().GetNullable(typeFrom); + typeFrom = TypeManager.GetNullable(typeFrom); if (fLiftDst && typeTo.IsNonNullableValueType) - typeTo = GetTypes().GetNullable(typeTo); + typeTo = TypeManager.GetNullable(typeTo); // Check for applicability. bool fFromImplicit = exprSrc != null ? canConvert(exprSrc, typeFrom, CONVERTTYPE.STANDARDANDNOUDC) : canConvert(typeSrc, typeFrom, CONVERTTYPE.STANDARDANDNOUDC); @@ -754,7 +751,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { continue; } - if (isConvInTable(prguci, convCur, atsCur, fFromImplicit, fToImplicit)) + if (IsConvInTable(prguci, convCur, atsCur, fFromImplicit, fToImplicit)) { // VSWhidbey 579325: duplicate conversions in the convInfo table cause false ambiguity: // If a user defined implicit conversion exists in a generic base type, @@ -855,21 +852,21 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics UdConvInfo uci = prguci[iuci]; // Get the substituted src and dst types. - typeFrom = GetTypes().SubstType(uci.Meth.Meth().Params[0], uci.Meth.GetType()); - typeTo = GetTypes().SubstType(uci.Meth.Meth().RetType, uci.Meth.GetType()); + typeFrom = TypeManager.SubstType(uci.Meth.Meth().Params[0], uci.Meth.GetType()); + typeTo = TypeManager.SubstType(uci.Meth.Meth().RetType, uci.Meth.GetType()); int ctypeLift = 0; // Lift the conversion if needed. if (fLiftSrc && typeFrom.IsNonNullableValueType) { - typeFrom = GetTypes().GetNullable(typeFrom); + typeFrom = TypeManager.GetNullable(typeFrom); ctypeLift++; } if (fLiftDst && typeTo.IsNonNullableValueType) { - typeTo = GetTypes().GetNullable(typeTo); + typeTo = TypeManager.GetNullable(typeTo); ctypeLift++; } @@ -956,8 +953,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(ctypeLiftBest <= 2); - typeFrom = GetTypes().SubstType(mwiBest.Meth().Params[0], mwiBest.GetType()); - typeTo = GetTypes().SubstType(mwiBest.Meth().RetType, mwiBest.GetType()); + typeFrom = TypeManager.SubstType(mwiBest.Meth().Params[0], mwiBest.GetType()); + typeTo = TypeManager.SubstType(mwiBest.Meth().RetType, mwiBest.GetType()); Expr exprDst; Expr pTransformedArgument = exprSrc; @@ -989,7 +986,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (typeFrom != typeSrcBase) { // There is an intermediate conversion. - NullableType pConversionNubSourceType = SymbolLoader.GetTypeManager().GetNullable(typeFrom); + NullableType pConversionNubSourceType = TypeManager.GetNullable(typeFrom); pConversionArgument = mustCast(exprSrc, pConversionNubSourceType); MarkAsIntermediateConversion(pConversionArgument); } @@ -1027,14 +1024,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - private RuntimeBinderException HandleAmbiguity(CType typeSrc, CType typeDst, List prguci, int iuciBestSrc, int iuciBestDst) + private static RuntimeBinderException HandleAmbiguity(CType typeSrc, CType typeDst, List prguci, int iuciBestSrc, int iuciBestDst) { Debug.Assert(0 <= iuciBestSrc && iuciBestSrc < prguci.Count); Debug.Assert(0 <= iuciBestDst && iuciBestDst < prguci.Count); - return ErrorContext.Error(ErrorCode.ERR_AmbigUDConv, prguci[iuciBestSrc].Meth, prguci[iuciBestDst].Meth, typeSrc, typeDst); + return ErrorHandling.Error(ErrorCode.ERR_AmbigUDConv, prguci[iuciBestSrc].Meth, prguci[iuciBestDst].Meth, typeSrc, typeDst); } - private void MarkAsIntermediateConversion(Expr pExpr) + private static void MarkAsIntermediateConversion(Expr pExpr) { for (;;) { @@ -1100,7 +1097,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (ftSrc == FUNDTYPE.FT_STRUCT || ftDest == FUNDTYPE.FT_STRUCT) { // Do constant folding involving decimal constants. - Expr expr = bindDecimalConstCast(typeDest, exprSrc.Type, constSrc); + Expr expr = BindDecimalConstCast(typeDest, exprSrc.Type, constSrc); if (expr == null) { @@ -1342,7 +1339,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics /* * Bind a constant cast to or from decimal. Return null if cast can't be done. */ - private Expr bindDecimalConstCast(CType destType, CType srcType, ExprConstant src) + private static Expr BindDecimalConstCast(CType destType, CType srcType, ExprConstant src) { CType typeDecimal = SymbolLoader.GetPredefindType(PredefinedType.PT_DECIMAL); ConstVal cv; @@ -1447,14 +1444,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Create the cast that was the original tree for this thing. return exprConst; } + return null; } - private bool canExplicitConversionBeBoundInUncheckedContext(Expr exprSrc, CType typeSrc, CType typeDest, CONVERTTYPE flags) + private bool CanExplicitConversionBeBoundInUncheckedContext(Expr exprSrc, CType typeSrc, CType typeDest, CONVERTTYPE flags) { - BindingContext ctx = new BindingContext(Context); Debug.Assert(typeDest != null); - return (new ExpressionBinder(ctx)).BindExplicitConversion(exprSrc, typeSrc, typeDest, flags); + return new ExpressionBinder(new BindingContext(Context)).BindExplicitConversion(exprSrc, typeSrc, typeDest, flags); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversions.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversions.cs index 8859d7c..f9b91e0 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversions.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversions.cs @@ -24,8 +24,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics when the source is a reference type and the destination is a base type of the source. Note that typeDst.IsRefType() may still return false (when both are type parameters). ***************************************************************************************************/ - public static bool FImpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst) => - typeSrc.IsReferenceType && loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst); + public static bool FImpRefConv(CType typeSrc, CType typeDst) => + typeSrc.IsReferenceType && SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst); /*************************************************************************************************** Determine whether there is an explicit or implicit reference conversion (or identity conversion) @@ -71,7 +71,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics The latter two cases can happen with type variables even though the other type variable is not a reference type. ***************************************************************************************************/ - public static bool FExpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst) + public static bool FExpRefConv(CType typeSrc, CType typeDst) { Debug.Assert(typeSrc != null); Debug.Assert(typeDst != null); @@ -79,8 +79,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // is there an implicit reference conversion in either direction? // this handles the bulk of the cases ... - if (loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) || - loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc)) + if (SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) || + SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc)) { return true; } @@ -118,7 +118,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { return arrSrc.Rank == arrDst.Rank && arrSrc.IsSZArray == arrDst.IsSZArray - && FExpRefConv(loader, arrSrc.ElementType, arrDst.ElementType); + && FExpRefConv(arrSrc.ElementType, arrDst.ElementType); } // * From a one-dimensional array-type S[] to System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyList @@ -136,8 +136,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - AggregateSymbol aggIList = loader.GetPredefAgg(PredefinedType.PT_G_ILIST); - AggregateSymbol aggIReadOnlyList = loader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); + AggregateSymbol aggIList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST); + AggregateSymbol aggIReadOnlyList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !SymbolLoader.IsBaseAggregate(aggIList, aggDst.OwningAggregate)) && @@ -147,13 +147,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - return FExpRefConv(loader, arrSrc.ElementType, typeArgsAll[0]); + return FExpRefConv(arrSrc.ElementType, typeArgsAll[0]); } if (typeDst is ArrayType arrayDest && typeSrc is AggregateType aggtypeSrc) { // * From System.Array and the interfaces it implements, to any array-type. - if (loader.HasIdentityOrImplicitReferenceConversion(loader.GetPredefindType(PredefinedType.PT_ARRAY), typeSrc)) + if (SymbolLoader.HasIdentityOrImplicitReferenceConversion(SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY), typeSrc)) { return true; } @@ -167,8 +167,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - AggregateSymbol aggIList = loader.GetPredefAgg(PredefinedType.PT_G_ILIST); - AggregateSymbol aggIReadOnlyList = loader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); + AggregateSymbol aggIList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST); + AggregateSymbol aggIReadOnlyList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !SymbolLoader.IsBaseAggregate(aggIList, aggtypeSrc.OwningAggregate)) && @@ -182,9 +182,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType typeLst = aggtypeSrc.TypeArgsAll[0]; Debug.Assert(!(typeArr is MethodGroupType)); - return typeArr == typeLst || FExpRefConv(loader, typeArr, typeLst); + return typeArr == typeLst || FExpRefConv(typeArr, typeLst); } - if (HasGenericDelegateExplicitReferenceConversion(loader, typeSrc, typeDst)) + if (HasGenericDelegateExplicitReferenceConversion(typeSrc, typeDst)) { return true; } @@ -193,13 +193,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // conversion of T . U, where T : class, U // .. these constraints implies where U : class - return loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst); + return SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst); } else if (typeDst.IsReferenceType) { // conversion of T . U, where U : class, T // .. these constraints implies where T : class - return loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc); + return SymbolLoader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc); } return false; } @@ -216,16 +216,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics o If type parameter Xi is declared to be contravariant ("in") then either Si must be identical to Ti, or Si and Ti must both be reference types. ***************************************************************************************************/ - public static bool HasGenericDelegateExplicitReferenceConversion(SymbolLoader loader, CType source, CType target) => - target is AggregateType aggTarget && HasGenericDelegateExplicitReferenceConversion(loader, source, aggTarget); + public static bool HasGenericDelegateExplicitReferenceConversion(CType source, CType target) => + target is AggregateType aggTarget && HasGenericDelegateExplicitReferenceConversion(source, aggTarget); - public static bool HasGenericDelegateExplicitReferenceConversion(SymbolLoader loader, CType pSource, AggregateType pTarget) + public static bool HasGenericDelegateExplicitReferenceConversion(CType pSource, AggregateType pTarget) { if (!(pSource is AggregateType aggSrc) || !aggSrc.IsDelegateType || !pTarget.IsDelegateType || aggSrc.OwningAggregate != pTarget.OwningAggregate || - loader.HasIdentityOrImplicitReferenceConversion(aggSrc, pTarget)) + SymbolLoader.HasIdentityOrImplicitReferenceConversion(aggSrc, pTarget)) { return false; } @@ -257,7 +257,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (pParam.Covariant) { - if (!FExpRefConv(loader, pSourceArg, pTargetArg)) + if (!FExpRefConv(pSourceArg, pTargetArg)) { return false; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/AggregateDeclaration.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/AggregateDeclaration.cs deleted file mode 100644 index 8dbc721..0000000 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/AggregateDeclaration.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Reflection; - -namespace Microsoft.CSharp.RuntimeBinder.Semantics -{ - // ---------------------------------------------------------------------------- - // - // AggregateDeclaration - // - // AggregateDeclaration - represents a declaration of an aggregate type. With partial classes, - // an aggregate type might be declared in multiple places. This symbol represents - // on of the declarations. - // - // parent is the containing Declaration. - // ---------------------------------------------------------------------------- - - // Either a ClassNode or a DelegateNode - internal sealed class AggregateDeclaration : ParentSymbol - { - public NamespaceOrAggregateSymbol bag; - - public AggregateDeclaration declNext; - - public AggregateSymbol Agg() - { - return bag as AggregateSymbol; - } - - public Assembly GetAssembly() - { - return Agg().AssociatedAssembly; - } - } -} diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs index e8101c8..5cc7580 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/EXPRExtensions.cs @@ -10,20 +10,21 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal static class EXPRExtensions { - public static Expr Map(this Expr expr, ExprFactory factory, Func f) + public static Expr Map(this Expr expr, Func f) { Debug.Assert(f != null); - Debug.Assert(factory != null); if (expr == null) - return f(expr); + { + return f(null); + } Expr result = null; Expr tail = null; foreach (Expr item in expr.ToEnumerable()) { Expr mappedItem = f(item); - factory.AppendItemToList(mappedItem, ref result, ref tail); + ExprFactory.AppendItemToList(mappedItem, ref result, ref tail); } return result; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs index d53d1a7..a4f419b 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs @@ -7,7 +7,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { // ---------------------------------------------------------------------------- // BindExplicitConversion @@ -196,7 +196,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr valueSrc = _exprSrc; if (valueSrc.Type is NullableType) { - valueSrc = _binder.BindNubValue(valueSrc); + valueSrc = BindNubValue(valueSrc); } Debug.Assert(valueSrc.Type == _typeSrc.StripNubs()); @@ -238,8 +238,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - AggregateSymbol aggIList = GetSymbolLoader().GetPredefAgg(PredefinedType.PT_G_ILIST); - AggregateSymbol aggIReadOnlyList = GetSymbolLoader().GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); + AggregateSymbol aggIList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST); + AggregateSymbol aggIReadOnlyList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !SymbolLoader.IsBaseAggregate(aggIList, aggDest.OwningAggregate)) && @@ -252,7 +252,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType typeArr = arrSrc.ElementType; CType typeLst = aggDest.TypeArgsAll[0]; - if (!CConversions.FExpRefConv(GetSymbolLoader(), typeArr, typeLst)) + if (!CConversions.FExpRefConv(typeArr, typeLst)) { return false; } @@ -278,8 +278,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - AggregateSymbol aggIList = GetSymbolLoader().GetPredefAgg(PredefinedType.PT_G_ILIST); - AggregateSymbol aggIReadOnlyList = GetSymbolLoader().GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); + AggregateSymbol aggIList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_ILIST); + AggregateSymbol aggIReadOnlyList = SymbolLoader.GetPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !SymbolLoader.IsBaseAggregate(aggIList, aggSrc.OwningAggregate)) && @@ -293,7 +293,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType typeLst = aggSrc.TypeArgsAll[0]; Debug.Assert(!(typeArr is MethodGroupType)); - if (typeArr != typeLst && !CConversions.FExpRefConv(GetSymbolLoader(), typeArr, typeLst)) + if (typeArr != typeLst && !CConversions.FExpRefConv(typeArr, typeLst)) { return false; } @@ -321,10 +321,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; // Ranks do not match. } - if (CConversions.FExpRefConv(GetSymbolLoader(), arraySrc.ElementType, arrayDest.ElementType)) + if (CConversions.FExpRefConv(arraySrc.ElementType, arrayDest.ElementType)) { if (_needsExprDest) + { _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK); + } + return true; } @@ -352,7 +355,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // * From System.Array and the interfaces it implements, to any array-type. - if (_binder.canConvert(_binder.GetPredefindType(PredefinedType.PT_ARRAY), _typeSrc, CONVERTTYPE.NOUDC)) + if (_binder.canConvert(GetPredefindType(PredefinedType.PT_ARRAY), _typeSrc, CONVERTTYPE.NOUDC)) { if (_needsExprDest) _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK); @@ -670,7 +673,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics AggregateSymbol aggSrc = atSrc.OwningAggregate; AggregateSymbol aggDest = aggTypeDest.OwningAggregate; - if (GetSymbolLoader().HasBaseConversion(aggTypeDest, atSrc)) + if (SymbolLoader.HasBaseConversion(aggTypeDest, atSrc)) { if (_needsExprDest) { @@ -687,7 +690,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) || (aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) || (aggSrc.IsInterface() && aggDest.IsInterface()) || - CConversions.HasGenericDelegateExplicitReferenceConversion(GetSymbolLoader(), _typeSrc, aggTypeDest)) + CConversions.HasGenericDelegateExplicitReferenceConversion(_typeSrc, aggTypeDest)) { if (_needsExprDest) _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK | (_exprSrc?.Flags & EXPRFLAG.EXF_CANTBENULL ?? 0)); @@ -757,11 +760,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return AggCastResult.Failure; } - - private SymbolLoader GetSymbolLoader() - { - return _binder.GetSymbolLoader(); - } } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs index b1013e5..83465b8 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExprFactory.cs @@ -8,90 +8,72 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class ExprFactory + internal static class ExprFactory { - private readonly GlobalSymbolContext _globalSymbolContext; - - public ExprFactory(GlobalSymbolContext globalSymbolContext) - { - Debug.Assert(globalSymbolContext != null); - _globalSymbolContext = globalSymbolContext; - } - private TypeManager Types => _globalSymbolContext.GetTypes(); - - private BSYMMGR GlobalSymbols => _globalSymbolContext.GetGlobalSymbols(); - - public ExprCall CreateCall(EXPRFLAG flags, CType type, Expr arguments, ExprMemberGroup memberGroup, MethWithInst method) => + public static ExprCall CreateCall(EXPRFLAG flags, CType type, Expr arguments, ExprMemberGroup memberGroup, MethWithInst method) => new ExprCall(type, flags, arguments, memberGroup, method); - public ExprField CreateField(CType type, Expr optionalObject, FieldWithType field) => + public static ExprField CreateField(CType type, Expr optionalObject, FieldWithType field) => new ExprField(type, optionalObject, field); - public ExprArrayInit CreateArrayInit(CType type, Expr arguments, Expr argumentDimensions, int[] dimSizes, int dimSize) => + public static ExprArrayInit CreateArrayInit(CType type, Expr arguments, Expr argumentDimensions, int[] dimSizes, int dimSize) => new ExprArrayInit(type, arguments, argumentDimensions, dimSizes, dimSize); - public ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod) => + public static ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod) => new ExprProperty(type, optionalObjectThrough, arguments, memberGroup, property, setMethod); - public ExprMemberGroup CreateMemGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol memberSymbol, Expr obj, CMemberLookupResults memberLookupResults) => - new ExprMemberGroup(flags, name, typeArgs, symKind, parentType, memberSymbol, obj, memberLookupResults); + public static ExprMemberGroup CreateMemGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, Expr obj, CMemberLookupResults memberLookupResults) => + new ExprMemberGroup(flags, name, typeArgs, symKind, parentType, obj, memberLookupResults); - public ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method) + public static ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method) { Name name = method.Sym?.name; - MethodOrPropertySymbol methProp = method.MethProp(); - - CType type = method.GetType(); - return CreateMemGroup( - 0, name, method.TypeArgs, methProp?.getKind() ?? SYMKIND.SK_MethodSymbol, method.GetType(), methProp, - obj, new CMemberLookupResults(GlobalSymbols.AllocParams(1, new[] {type}), name)); + 0, name, method.TypeArgs, method.MethProp()?.getKind() ?? SYMKIND.SK_MethodSymbol, method.GetType(), + obj, new CMemberLookupResults(TypeArray.Allocate((CType)method.GetType()), name)); } - public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst method) => + public static ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst method) => new ExprUserDefinedConversion(arg, call, method); - public ExprCast CreateCast(CType type, Expr argument) => CreateCast(0, type, argument); + public static ExprCast CreateCast(CType type, Expr argument) => CreateCast(0, type, argument); - public ExprCast CreateCast(EXPRFLAG flags, CType type, Expr argument) => new ExprCast(flags, type, argument); + public static ExprCast CreateCast(EXPRFLAG flags, CType type, Expr argument) => new ExprCast(flags, type, argument); - public ExprLocal CreateLocal(LocalVariableSymbol local) => new ExprLocal(local); + public static ExprLocal CreateLocal(LocalVariableSymbol local) => new ExprLocal(local); - public ExprBoundLambda CreateAnonymousMethod(AggregateType delegateType, Scope argumentScope, Expr expression) => + public static ExprBoundLambda CreateAnonymousMethod(AggregateType delegateType, Scope argumentScope, Expr expression) => new ExprBoundLambda(delegateType, argumentScope, expression); - public ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi) => + public static ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi) => CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs); - public ExprMethodInfo CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters) - { - return new ExprMethodInfo( - Types.GetPredefAgg(method.IsConstructor() ? PredefinedType.PT_CONSTRUCTORINFO : PredefinedType.PT_METHODINFO).getThisType(), + public static ExprMethodInfo CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters) => + new ExprMethodInfo( + TypeManager.GetPredefAgg(method.IsConstructor() ? PredefinedType.PT_CONSTRUCTORINFO : PredefinedType.PT_METHODINFO).getThisType(), method, methodType, methodParameters); - } - public ExprPropertyInfo CreatePropertyInfo(PropertySymbol prop, AggregateType propertyType) => - new ExprPropertyInfo(Types.GetPredefAgg(PredefinedType.PT_PROPERTYINFO).getThisType(), prop, propertyType); + public static ExprPropertyInfo CreatePropertyInfo(PropertySymbol prop, AggregateType propertyType) => + new ExprPropertyInfo(TypeManager.GetPredefAgg(PredefinedType.PT_PROPERTYINFO).getThisType(), prop, propertyType); - public ExprFieldInfo CreateFieldInfo(FieldSymbol field, AggregateType fieldType) => - new ExprFieldInfo(field, fieldType, Types.GetPredefAgg(PredefinedType.PT_FIELDINFO).getThisType()); + public static ExprFieldInfo CreateFieldInfo(FieldSymbol field, AggregateType fieldType) => + new ExprFieldInfo(field, fieldType, TypeManager.GetPredefAgg(PredefinedType.PT_FIELDINFO).getThisType()); - public ExprTypeOf CreateTypeOf(CType sourceType) => - new ExprTypeOf(Types.GetPredefAgg(PredefinedType.PT_TYPE).getThisType(), sourceType); + public static ExprTypeOf CreateTypeOf(CType sourceType) => + new ExprTypeOf(TypeManager.GetPredefAgg(PredefinedType.PT_TYPE).getThisType(), sourceType); - - public ExprUserLogicalOp CreateUserLogOp(CType type, Expr trueFalseCall, ExprCall operatorCall) => + public static ExprUserLogicalOp CreateUserLogOp(CType type, Expr trueFalseCall, ExprCall operatorCall) => new ExprUserLogicalOp(type, trueFalseCall, operatorCall); - public ExprConcat CreateConcat(Expr first, Expr second) => new ExprConcat(first, second); + public static ExprConcat CreateConcat(Expr first, Expr second) => new ExprConcat(first, second); - public ExprConstant CreateStringConstant(string str) => - CreateConstant(Types.GetPredefAgg(PredefinedType.PT_STRING).getThisType(), ConstVal.Get(str)); + public static ExprConstant CreateStringConstant(string str) => + CreateConstant(TypeManager.GetPredefAgg(PredefinedType.PT_STRING).getThisType(), ConstVal.Get(str)); - public ExprMultiGet CreateMultiGet(EXPRFLAG flags, CType type, ExprMulti multi) => + public static ExprMultiGet CreateMultiGet(EXPRFLAG flags, CType type, ExprMulti multi) => new ExprMultiGet(type, flags, multi); - public ExprMulti CreateMulti(EXPRFLAG flags, CType type, Expr left, Expr op) => + public static ExprMulti CreateMulti(EXPRFLAG flags, CType type, Expr left, Expr op) => new ExprMulti(type, flags, left, op); //////////////////////////////////////////////////////////////////////////////// @@ -102,7 +84,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // This returns a null for reference types and an EXPRZEROINIT for all others. - public Expr CreateZeroInit(CType type) + public static Expr CreateZeroInit(CType type) { Debug.Assert(type != null); @@ -139,24 +121,24 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - public ExprConstant CreateConstant(CType type, ConstVal constVal) => new ExprConstant(type, constVal); + public static ExprConstant CreateConstant(CType type, ConstVal constVal) => new ExprConstant(type, constVal); - public ExprConstant CreateIntegerConstant(int x) => - CreateConstant(Types.GetPredefAgg(PredefinedType.PT_INT).getThisType(), ConstVal.Get(x)); + public static ExprConstant CreateIntegerConstant(int x) => + CreateConstant(TypeManager.GetPredefAgg(PredefinedType.PT_INT).getThisType(), ConstVal.Get(x)); - public ExprConstant CreateBoolConstant(bool b) => - CreateConstant(Types.GetPredefAgg(PredefinedType.PT_BOOL).getThisType(), ConstVal.Get(b)); + public static ExprConstant CreateBoolConstant(bool b) => + CreateConstant(TypeManager.GetPredefAgg(PredefinedType.PT_BOOL).getThisType(), ConstVal.Get(b)); - public ExprArrayIndex CreateArrayIndex(CType type, Expr array, Expr index) => + public static ExprArrayIndex CreateArrayIndex(CType type, Expr array, Expr index) => new ExprArrayIndex(type, array, index); - public ExprBinOp CreateBinop(ExpressionKind exprKind, CType type, Expr left, Expr right) => + public static ExprBinOp CreateBinop(ExpressionKind exprKind, CType type, Expr left, Expr right) => new ExprBinOp(exprKind, type, left, right); - public ExprUnaryOp CreateUnaryOp(ExpressionKind exprKind, CType type, Expr operand) => + public static ExprUnaryOp CreateUnaryOp(ExpressionKind exprKind, CType type, Expr operand) => new ExprUnaryOp(exprKind, type, operand); - public ExprOperator CreateOperator(ExpressionKind exprKind, CType type, Expr arg1, Expr arg2) + public static ExprOperator CreateOperator(ExpressionKind exprKind, CType type, Expr arg1, Expr arg2) { Debug.Assert(arg1 != null); Debug.Assert(exprKind.IsUnaryOperator() == (arg2 == null)); @@ -165,15 +147,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics : CreateBinop(exprKind, type, arg1, arg2); } - - public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod) => + public static ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod) => new ExprBinOp(exprKind, type, left, right, call, userMethod); // The call may be lifted, but we do not mark the outer binop as lifted. - public ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType type, Expr operand, ExprCall call, MethPropWithInst userMethod) => + public static ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType type, Expr operand, ExprCall call, MethPropWithInst userMethod) => new ExprUnaryOp(exprKind, type, operand, call, userMethod); - public ExprUnaryOp CreateNeg(EXPRFLAG flags, Expr operand) + public static ExprUnaryOp CreateNeg(EXPRFLAG flags, Expr operand) { Debug.Assert(operand != null); ExprUnaryOp unary = CreateUnaryOp(ExpressionKind.Negate, operand.Type, operand); @@ -184,22 +165,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// // Create a node that evaluates the first, evaluates the second, results in the second. - public ExprBinOp CreateSequence(Expr first, Expr second) => + public static ExprBinOp CreateSequence(Expr first, Expr second) => CreateBinop(ExpressionKind.Sequence, second.Type, first, second); //////////////////////////////////////////////////////////////////////////////// // Create a node that evaluates the first, evaluates the second, results in the first. - public ExprAssignment CreateAssignment(Expr left, Expr right) => new ExprAssignment(left, right); + public static ExprAssignment CreateAssignment(Expr left, Expr right) => new ExprAssignment(left, right); //////////////////////////////////////////////////////////////////////////////// - public ExprNamedArgumentSpecification CreateNamedArgumentSpecification(Name name, Expr value) => + public static ExprNamedArgumentSpecification CreateNamedArgumentSpecification(Name name, Expr value) => new ExprNamedArgumentSpecification(name, value); - public ExprWrap CreateWrap(Expr expression) => new ExprWrap(expression); + public static ExprWrap CreateWrap(Expr expression) => new ExprWrap(expression); - public ExprBinOp CreateSave(ExprWrap wrap) + public static ExprBinOp CreateSave(ExprWrap wrap) { Debug.Assert(wrap != null); ExprBinOp expr = CreateBinop(ExpressionKind.Save, wrap.Type, wrap.OptionalExpression, wrap); @@ -207,13 +188,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return expr; } - public ExprConstant CreateNull() => CreateConstant(NullType.Instance, default); + public static ExprConstant CreateNull() => CreateConstant(NullType.Instance, default); - public void AppendItemToList( - Expr newItem, - ref Expr first, - ref Expr last - ) + public static void AppendItemToList(Expr newItem, ref Expr first, ref Expr last) { if (newItem == null) { @@ -241,14 +218,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics last = list.OptionalNextListNode; } - public ExprList CreateList(Expr op1, Expr op2) => new ExprList(op1, op2); + public static ExprList CreateList(Expr op1, Expr op2) => new ExprList(op1, op2); - public ExprList CreateList(Expr op1, Expr op2, Expr op3) => CreateList(op1, CreateList(op2, op3)); + public static ExprList CreateList(Expr op1, Expr op2, Expr op3) => CreateList(op1, CreateList(op2, op3)); - public ExprList CreateList(Expr op1, Expr op2, Expr op3, Expr op4) => + public static ExprList CreateList(Expr op1, Expr op2, Expr op3, Expr op4) => CreateList(op1, CreateList(op2, CreateList(op3, op4))); - public ExprClass CreateClass(CType type) => new ExprClass(type); + public static ExprClass CreateClass(CType type) => new ExprClass(type); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs index a3875ec..79fe57d 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs @@ -143,7 +143,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics None } - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { // ExpressionBinder - General Rules // @@ -260,112 +260,21 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Factory method sets the "Do Children have Errors?" bit - not done manually. // Once constructed Expression trees are not mutated - doesn't work easily for statements unfortunately. - private delegate Expr PfnBindBinOp(ExpressionKind ek, EXPRFLAG flags, Expr op1, Expr op2); - private delegate Expr PfnBindUnaOp(ExpressionKind ek, EXPRFLAG flags, Expr op); + private delegate Expr PfnBindBinOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr op1, Expr op2); + private delegate Expr PfnBindUnaOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr op); - private BindingContext Context; - public BindingContext GetContext() { return Context; } - private CNullable m_nullable; + public BindingContext Context { get; } public ExpressionBinder(BindingContext context) { Context = context; - m_nullable = new CNullable(GetSymbolLoader(), GetErrorContext(), GetExprFactory()); - g_binopSignatures = new BinOpSig[] - { - new BinOpSig (PredefinedType.PT_INT, PredefinedType.PT_INT, BinOpMask.Integer, 8, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), - new BinOpSig (PredefinedType.PT_UINT, PredefinedType.PT_UINT, BinOpMask.Integer, 7, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), - new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_LONG, BinOpMask.Integer, 6, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), - new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_ULONG, BinOpMask.Integer, 5, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), - /* ERROR */ - new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_LONG, BinOpMask.Integer, 4, null, OpSigFlags.Value, BinOpFuncKind.None ), - /* ERROR */ - new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_ULONG, BinOpMask.Integer, 3, null, OpSigFlags.Value, BinOpFuncKind.None ), - new BinOpSig (PredefinedType.PT_FLOAT, PredefinedType.PT_FLOAT, BinOpMask.Real, 1, BindRealBinOp, OpSigFlags.Value, BinOpFuncKind.RealBinOp ), - new BinOpSig (PredefinedType.PT_DOUBLE, PredefinedType.PT_DOUBLE, BinOpMask.Real, 0, BindRealBinOp, OpSigFlags.Value, BinOpFuncKind.RealBinOp ), - new BinOpSig (PredefinedType.PT_DECIMAL, PredefinedType.PT_DECIMAL, BinOpMask.Real, 0, BindDecBinOp, OpSigFlags.Value, BinOpFuncKind.DecBinOp ), - new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_STRING, BinOpMask.Equal, 0, BindStrCmpOp, OpSigFlags.Reference, BinOpFuncKind.StrCmpOp ), - new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_STRING, BinOpMask.Add, 2, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), - new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_OBJECT, BinOpMask.Add, 1, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), - new BinOpSig (PredefinedType.PT_OBJECT, PredefinedType.PT_STRING, BinOpMask.Add, 0, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), - new BinOpSig (PredefinedType.PT_INT, PredefinedType.PT_INT, BinOpMask.Shift, 3, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), - new BinOpSig (PredefinedType.PT_UINT, PredefinedType.PT_INT, BinOpMask.Shift, 2, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), - new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_INT, BinOpMask.Shift, 1, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), - new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_INT, BinOpMask.Shift, 0, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), - new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.BoolNorm, 0, BindBoolBinOp, OpSigFlags.Value, BinOpFuncKind.BoolBinOp ), - // Make boolean logical operators liftable so that they don't give funny short circuiting semantics. - // This is for DDBugs 677075. - new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.Logical, 0, BindBoolBinOp, OpSigFlags.BoolBit, BinOpFuncKind.BoolBinOp ), - new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.Bitwise, 0, BindLiftedBoolBitwiseOp, OpSigFlags.BoolBit, BinOpFuncKind.BoolBitwiseOp ), - }; - g_rguos = new UnaOpSig[] - { - new UnaOpSig( PredefinedType.PT_INT, UnaOpMask.Signed, 7, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), - new UnaOpSig( PredefinedType.PT_UINT, UnaOpMask.Unsigned, 6, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), - new UnaOpSig( PredefinedType.PT_LONG, UnaOpMask.Signed, 5, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), - new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.Unsigned, 4, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), - /* ERROR */ - new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.Minus, 3, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_FLOAT, UnaOpMask.Real, 1, BindRealUnaOp, UnaOpFuncKind.RealUnaOp ), - new UnaOpSig( PredefinedType.PT_DOUBLE, UnaOpMask.Real, 0, BindRealUnaOp, UnaOpFuncKind.RealUnaOp ), - new UnaOpSig( PredefinedType.PT_DECIMAL, UnaOpMask.Real, 0, BindDecUnaOp, UnaOpFuncKind.DecUnaOp ), - new UnaOpSig( PredefinedType.PT_BOOL, UnaOpMask.Bool, 0, BindBoolUnaOp, UnaOpFuncKind.BoolUnaOp ), - new UnaOpSig( PredefinedType.PT_INT, UnaOpMask.IncDec, 6, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_UINT, UnaOpMask.IncDec, 5, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_LONG, UnaOpMask.IncDec, 4, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.IncDec, 3, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_FLOAT, UnaOpMask.IncDec, 1, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_DOUBLE, UnaOpMask.IncDec, 0, null, UnaOpFuncKind.None ), - new UnaOpSig( PredefinedType.PT_DECIMAL, UnaOpMask.IncDec, 0, null, UnaOpFuncKind.None ), - }; } - private SymbolLoader GetSymbolLoader() { return SymbolLoader; } - - private SymbolLoader SymbolLoader - { - get - { - return Context.SymbolLoader; - } - } - - private CSemanticChecker SemanticChecker - { - get - { - return Context.SemanticChecker; - } - } - public CSemanticChecker GetSemanticChecker() { return SemanticChecker; } - - private ErrorHandling ErrorContext - { - get - { - return SymbolLoader.ErrorContext; - } - } - private ErrorHandling GetErrorContext() { return ErrorContext; } - - private BSYMMGR GetGlobalSymbols() - { - return GetSymbolLoader().getBSymmgr(); - } - - private TypeManager GetTypes() { return TypeManager; } - - private TypeManager TypeManager { get { return SymbolLoader.TypeManager; } } - - private ExprFactory GetExprFactory() { return ExprFactory; } - - private ExprFactory ExprFactory { get { return Context.ExprFactory; } } - - private AggregateType GetPredefindType(PredefinedType pt) + private static AggregateType GetPredefindType(PredefinedType pt) { Debug.Assert(pt != PredefinedType.PT_VOID); // use getVoidType() - return GetSymbolLoader().GetPredefindType(pt); + return SymbolLoader.GetPredefindType(pt); } private Expr GenerateAssignmentConversion(Expr op1, Expr op2, bool allowExplicit) => @@ -395,23 +304,24 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ArrayType pArrayType = pOp1.Type as ArrayType; Debug.Assert(pArrayType != null); CType elementType = pArrayType.ElementType; - checkUnsafe(elementType); // added to the binder so we don't bind to pointer ops + CheckUnsafe(elementType); // added to the binder so we don't bind to pointer ops // Check the rank of the array against the number of indices provided, and // convert the indexes to ints CType pDestType = ChooseArrayIndexType(pOp2); - Expr transformedIndices = pOp2.Map(GetExprFactory(), + ExpressionBinder binder = this; + Expr transformedIndices = pOp2.Map( x => { - Expr pTemp = mustConvert(x, pDestType); + Expr pTemp = binder.mustConvert(x, pDestType); return pDestType == pIntType ? pTemp - : GetExprFactory().CreateCast(EXPRFLAG.EXF_INDEXEXPR, pDestType, pTemp); + : ExprFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, pDestType, pTemp); }); // Allocate a new expression, the type is the element type of the array. // Array index operations are always lvalues. - return GetExprFactory().CreateArrayIndex(elementType, pOp1, transformedIndices); + return ExprFactory.CreateArrayIndex(elementType, pOp1, transformedIndices); } //////////////////////////////////////////////////////////////////////////////// @@ -430,7 +340,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Make the cast expr anyway, and if we find that we have a constant, then set the cast expr // as the original tree for the constant. Otherwise, return the cast expr. - ExprCast exprCast = GetExprFactory().CreateCast(exprFlags, typeDest, exprSrc); + ExprCast exprCast = ExprFactory.CreateCast(exprFlags, typeDest, exprSrc); if (Context.Checked) { exprCast.Flags |= EXPRFLAG.EXF_CHECKOVERFLOW; @@ -443,7 +353,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics exprSrc.Type.FundamentalType == typeDest.FundamentalType && (!exprSrc.Type.IsPredefType(PredefinedType.PT_STRING) || constant.Val.IsNullRef)) { - ExprConstant expr = GetExprFactory().CreateConstant(typeDest, constant.Val); + ExprConstant expr = ExprFactory.CreateConstant(typeDest, constant.Val); pexprDest = expr; return; } @@ -479,10 +389,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } else { - pReturnType = GetTypes().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs); + pReturnType = TypeManager.SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs); } - ExprCall pResult = GetExprFactory().CreateCall(0, pReturnType, pArguments, pMemGroup, mwi); + ExprCall pResult = ExprFactory.CreateCall(0, pReturnType, pArguments, pMemGroup, mwi); // Set the return type and flags for constructors. if ((flags & MemLookFlags.Ctor) != 0) @@ -509,10 +419,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Debug.Assert(fwt.GetType() != null && fwt.Field().getClass() == fwt.GetType().OwningAggregate); - CType pFieldType = GetTypes().SubstType(fwt.Field().GetType(), fwt.GetType()); + CType pFieldType = TypeManager.SubstType(fwt.Field().GetType(), fwt.GetType()); pOptionalObject = AdjustMemberObject(fwt, pOptionalObject); - checkUnsafe(pFieldType); // added to the binder so we don't bind to pointer ops + CheckUnsafe(pFieldType); // added to the binder so we don't bind to pointer ops // lvalue if the object is an lvalue (or it's static) and the field is not readonly. // Since dynamic objects for fields come from locals or casts/conversions on locals @@ -523,8 +433,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics AggregateType fieldType = null; // If this field is the backing field of a WindowsRuntime event then we need to bind to its // invocationlist property which is a delegate containing all the handlers. - if (fwt.Field().isEvent && fwt.Field().getEvent(GetSymbolLoader()) != null - && fwt.Field().getEvent(GetSymbolLoader()).IsWindowsRuntimeEvent) + if (fwt.Field().isEvent && fwt.Field().getEvent() != null + && fwt.Field().getEvent().IsWindowsRuntimeEvent) { fieldType = fwt.Field().GetType() as AggregateType; if (fieldType != null) @@ -532,12 +442,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Access event backing field (EventRegistrationTokenTable) using // EventRegistrationTokenTable.GetOrCreateEventRegistrationTokenTable() // to ensure non-null - pFieldType = GetTypes().GetParameterModifier(pFieldType, false); + pFieldType = TypeManager.GetParameterModifier(pFieldType, false); } } - ExprField pResult = GetExprFactory() - .CreateField(pFieldType, pOptionalObject, fwt); + ExprField pResult = ExprFactory.CreateField(pFieldType, pOptionalObject, fwt); Debug.Assert(BindingFlag.BIND_MEMBERSET == (BindingFlag)EXPRFLAG.EXF_MEMBERSET); pResult.Flags |= (EXPRFLAG)(bindFlags & BindingFlag.BIND_MEMBERSET); @@ -546,16 +455,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Name getOrCreateMethodName = NameManager.GetPredefinedName(PredefinedName.PN_GETORCREATEEVENTREGISTRATIONTOKENTABLE); - GetSymbolLoader() - .RuntimeBinderSymbolTable.PopulateSymbolTableWithName( - getOrCreateMethodName.Text, null, fieldType.AssociatedSystemType); + SymbolTable.PopulateSymbolTableWithName( + getOrCreateMethodName.Text, null, fieldType.AssociatedSystemType); MethodSymbol getOrCreateMethod = - GetSymbolLoader() - .LookupAggMember(getOrCreateMethodName, fieldType.OwningAggregate, symbmask_t.MASK_MethodSymbol) + SymbolLoader.LookupAggMember(getOrCreateMethodName, fieldType.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; MethPropWithInst getOrCreatempwi = new MethPropWithInst(getOrCreateMethod, fieldType); - ExprMemberGroup getOrCreateGrp = GetExprFactory().CreateMemGroup(null, getOrCreatempwi); + ExprMemberGroup getOrCreateGrp = ExprFactory.CreateMemGroup(null, getOrCreatempwi); Expr getOrCreateCall = BindToMethod( new MethWithInst(getOrCreatempwi), pResult, getOrCreateGrp, (MemLookFlags)MemLookFlags.None); @@ -564,16 +471,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Name invocationListName = NameManager.GetPredefinedName(PredefinedName.PN_INVOCATIONLIST); // InvocationList might not be populated in the symbol table as no one would have called it. - GetSymbolLoader() - .RuntimeBinderSymbolTable.PopulateSymbolTableWithName( - invocationListName.Text, null, fieldType.AssociatedSystemType); + SymbolTable.PopulateSymbolTableWithName(invocationListName.Text, null, fieldType.AssociatedSystemType); PropertySymbol invocationList = - GetSymbolLoader() - .LookupAggMember(invocationListName, fieldTypeSymbol, symbmask_t.MASK_PropertySymbol) + SymbolLoader.LookupAggMember(invocationListName, fieldTypeSymbol, symbmask_t.MASK_PropertySymbol) as PropertySymbol; MethPropWithInst mpwi = new MethPropWithInst(invocationList, fieldType); - ExprMemberGroup memGroup = GetExprFactory().CreateMemGroup(getOrCreateCall, mpwi); + ExprMemberGroup memGroup = ExprFactory.CreateMemGroup(getOrCreateCall, mpwi); PropWithType pwt = new PropWithType(invocationList, fieldType); Expr propertyExpr = BindToProperty(getOrCreateCall, pwt, bindFlags, null, memGroup); @@ -597,12 +501,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // the setter is actually an lvalue. Expr pObjectThrough = pObject; - PostBindProperty(pwt, pObject, out MethWithType mwtGet, out MethWithType mwtSet); + PostBindProperty(pwt, out MethWithType mwtGet, out MethWithType mwtSet); if (mwtGet && (!mwtSet || mwtSet.GetType() == mwtGet.GetType() || - GetSymbolLoader().HasBaseConversion(mwtGet.GetType(), mwtSet.GetType()) + SymbolLoader.HasBaseConversion(mwtGet.GetType(), mwtSet.GetType()) ) ) { @@ -618,7 +522,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } pMemGroup.OptionalObject = pObject; - CType pReturnType = GetTypes().SubstType(pwt.Prop().RetType, pwt.GetType()); + CType pReturnType = TypeManager.SubstType(pwt.Prop().RetType, pwt.GetType()); // if we are doing a get on this thing, and there is no get, and // most importantly, we are not leaving the arguments to be bound by the array index @@ -627,7 +531,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (!mwtGet) { - throw ErrorContext.Error(ErrorCode.ERR_PropertyLacksGet, pwt); + throw ErrorHandling.Error(ErrorCode.ERR_PropertyLacksGet, pwt); } CType type = null; @@ -636,20 +540,20 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics type = pObjectThrough.Type; } - ACCESSERROR error = SemanticChecker.CheckAccess2(mwtGet.Meth(), mwtGet.GetType(), ContextForMemberLookup(), type); + ACCESSERROR error = CSemanticChecker.CheckAccess2(mwtGet.Meth(), mwtGet.GetType(), ContextForMemberLookup, type); if (error != ACCESSERROR.ACCESSERROR_NOERROR) { // if the get exists, but is not accessible, give an error. if (error == ACCESSERROR.ACCESSERROR_NOACCESSTHRU) { - throw ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, pwt, type, ContextForMemberLookup()); + throw ErrorHandling.Error(ErrorCode.ERR_BadProtectedAccess, pwt, type, ContextForMemberLookup); } - throw ErrorContext.Error(ErrorCode.ERR_InaccessibleGetter, pwt); + throw ErrorHandling.Error(ErrorCode.ERR_InaccessibleGetter, pwt); } } - ExprProperty result = GetExprFactory().CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, mwtSet); + ExprProperty result = ExprFactory.CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, mwtSet); if (result.OptionalArguments != null) { verifyMethodArgs(result, pObjectThrough?.Type); @@ -662,7 +566,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal Expr bindUDUnop(ExpressionKind ek, Expr arg) { - Name pName = ekName(ek); + Name pName = ExpressionKindName(ek); Debug.Assert(pName != null); CType typeSrc = arg.Type; @@ -690,12 +594,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics MethodSymbol methCur = null; AggregateType atsCur = (AggregateType)typeSrc; - for (; ;) + for (;;) { // Find the next operator. - methCur = methCur == null - ? GetSymbolLoader().LookupAggMember(pName, atsCur.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol - : SymbolLoader.LookupNextSym(methCur, atsCur.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; + methCur = (methCur == null + ? SymbolLoader.LookupAggMember(pName, atsCur.OwningAggregate, symbmask_t.MASK_MethodSymbol) + : methCur.LookupNext(symbmask_t.MASK_MethodSymbol)) as MethodSymbol; if (methCur == null) { @@ -723,25 +627,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(methCur.typeVars.Count == 0); - TypeArray paramsCur = GetTypes().SubstTypeArray(methCur.Params, atsCur); + TypeArray paramsCur = TypeManager.SubstTypeArray(methCur.Params, atsCur); CType typeParam = paramsCur[0]; NullableType nubParam; if (canConvert(arg, typeParam)) { methFirstList.Add(new CandidateFunctionMember( - new MethPropWithInst(methCur, atsCur, BSYMMGR.EmptyTypeArray()), + new MethPropWithInst(methCur, atsCur, TypeArray.Empty), paramsCur, 0, false)); } else if (typeParam.IsNonNullableValueType && - GetTypes().SubstType(methCur.RetType, atsCur).IsNonNullableValueType && - canConvert(arg, nubParam = GetTypes().GetNullable(typeParam))) + TypeManager.SubstType(methCur.RetType, atsCur).IsNonNullableValueType && + canConvert(arg, nubParam = TypeManager.GetNullable(typeParam))) { methFirstList.Add(new CandidateFunctionMember( - new MethPropWithInst(methCur, atsCur, BSYMMGR.EmptyTypeArray()), - GetGlobalSymbols().AllocParams(1, new CType[] { nubParam }), + new MethPropWithInst(methCur, atsCur, TypeArray.Empty), + TypeArray.Allocate(nubParam), 1, false)); } @@ -757,7 +661,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (pmethBest == null) { // No winner, so its an ambiguous call... - throw ErrorContext.Error(ErrorCode.ERR_AmbigCall, pmethAmbig1.mpwi, pmethAmbig2.mpwi); + throw ErrorHandling.Error(ErrorCode.ERR_AmbigCall, pmethAmbig1.mpwi, pmethAmbig2.mpwi); } ExprCall call; @@ -771,7 +675,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics call = BindUDUnopCall(arg, pmethBest.@params[0], pmethBest.mpwi); } - return GetExprFactory().CreateUserDefinedUnaryOperator(ek, call.Type, arg, call, pmethBest.mpwi); + return ExprFactory.CreateUserDefinedUnaryOperator(ek, call.Type, arg, call, pmethBest.mpwi); } private ExprCall BindLiftedUDUnop(Expr arg, CType typeArg, MethPropWithInst mpwi) @@ -784,18 +688,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(arg.Type is NullableType); - CType typeRet = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType()); + CType typeRet = TypeManager.SubstType(mpwi.Meth().RetType, mpwi.GetType()); if (!(typeRet is NullableType)) { - typeRet = GetTypes().GetNullable(typeRet); + typeRet = TypeManager.GetNullable(typeRet); } // First bind the non-lifted version for errors. Expr nonLiftedArg = mustCast(arg, typeRaw); ExprCall nonLiftedResult = BindUDUnopCall(nonLiftedArg, typeRaw, mpwi); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi); - ExprCall call = GetExprFactory().CreateCall(0, typeRet, arg, pMemGroup, null); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mpwi); + ExprCall call = ExprFactory.CreateCall(0, typeRet, arg, pMemGroup, null); call.MethWithInst = new MethWithInst(mpwi); call.CastOfNonLiftedResultToLiftedType = mustCast(nonLiftedResult, typeRet, 0); call.NullableCallLiftKind = NullableCallLiftKind.Operator; @@ -804,10 +708,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics private ExprCall BindUDUnopCall(Expr arg, CType typeArg, MethPropWithInst mpwi) { - CType typeRet = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType()); - checkUnsafe(typeRet); // added to the binder so we don't bind to pointer ops - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi); - ExprCall call = GetExprFactory().CreateCall(0, typeRet, mustConvert(arg, typeArg), pMemGroup, null); + CType typeRet = TypeManager.SubstType(mpwi.Meth().RetType, mpwi.GetType()); + CheckUnsafe(typeRet); // added to the binder so we don't bind to pointer ops + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mpwi); + ExprCall call = ExprFactory.CreateCall(0, typeRet, mustConvert(arg, typeArg), pMemGroup, null); call.MethWithInst = new MethWithInst(mpwi); verifyMethodArgs(call, mpwi.GetType()); return call; @@ -913,7 +817,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// // Report a bad operator types error to the user. - private RuntimeBinderException BadOperatorTypesError(Expr pOperand1, Expr pOperand2) + private static RuntimeBinderException BadOperatorTypesError(Expr pOperand1, Expr pOperand2) { // This is a hack, but we need to store the operation somewhere... the first argument's as // good a place as any. @@ -925,10 +829,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (pOperand2 != null) { Debug.Assert(pOperand2.Type != null); - return ErrorContext.Error(ErrorCode.ERR_BadBinaryOps, strOp, pOperand1.Type, pOperand2.Type); + return ErrorHandling.Error(ErrorCode.ERR_BadBinaryOps, strOp, pOperand1.Type, pOperand2.Type); } - return ErrorContext.Error(ErrorCode.ERR_BadUnaryOp, strOp, pOperand1.Type); + return ErrorHandling.Error(ErrorCode.ERR_BadUnaryOp, strOp, pOperand1.Type); } private static ErrorCode GetStandardLvalueError(CheckLvalueKind kind) @@ -957,12 +861,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics private void CheckPropertyAccess(MethWithType mwt, PropWithType pwtSlot, CType type) { - switch (SemanticChecker.CheckAccess2(mwt.Meth(), mwt.GetType(), ContextForMemberLookup(), type)) + switch (CSemanticChecker.CheckAccess2(mwt.Meth(), mwt.GetType(), ContextForMemberLookup, type)) { case ACCESSERROR.ACCESSERROR_NOACCESSTHRU: - throw ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, pwtSlot, type, ContextForMemberLookup()); + throw ErrorHandling.Error(ErrorCode.ERR_BadProtectedAccess, pwtSlot, type, ContextForMemberLookup); case ACCESSERROR.ACCESSERROR_NOACCESS: - throw ErrorContext.Error(mwt.Meth().isSetAccessor() ? ErrorCode.ERR_InaccessibleSetter : ErrorCode.ERR_InaccessibleGetter, pwtSlot); + throw ErrorHandling.Error(mwt.Meth().isSetAccessor() ? ErrorCode.ERR_InaccessibleSetter : ErrorCode.ERR_InaccessibleGetter, pwtSlot); } } @@ -1012,37 +916,37 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // SPEC VIOLATION: would be a breaking change. We currently discard "no op" casts // SPEC VIOLATION: very aggressively rather than generating an ExpressionKind.EK_CAST node. - throw ErrorContext.Error(ErrorCode.ERR_AssgReadonlyProp, prop.PropWithTypeSlot); + throw ErrorHandling.Error(ErrorCode.ERR_AssgReadonlyProp, prop.PropWithTypeSlot); case ExpressionKind.Field: ExprField field = (ExprField)expr; Debug.Assert(field.FieldWithType.Field().isReadOnly); - throw ErrorContext.Error( + throw ErrorHandling.Error( field.FieldWithType.Field().isStatic ? ErrorCode.ERR_AssgReadonlyStatic : ErrorCode.ERR_AssgReadonly); default: - throw ErrorContext.Error(GetStandardLvalueError(kind)); + throw ErrorHandling.Error(GetStandardLvalueError(kind)); } } - private void PostBindMethod(MethWithInst pMWI) + private static void PostBindMethod(MethWithInst pMWI) { MethodSymbol meth = pMWI.Meth(); if (meth.RetType != null) { - checkUnsafe(meth.RetType); + CheckUnsafe(meth.RetType); // We need to check unsafe on the parameters as well, since we cannot check in conversion. foreach (CType type in meth.Params.Items) { - checkUnsafe(type); + CheckUnsafe(type); } } } - private void PostBindProperty(PropWithType pwt, Expr pObject, out MethWithType pmwtGet, out MethWithType pmwtSet) + private static void PostBindProperty(PropWithType pwt, out MethWithType pmwtGet, out MethWithType pmwtSet) { PropertySymbol prop = pwt.Prop(); Debug.Assert(prop != null); @@ -1056,7 +960,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (prop.RetType != null) { - checkUnsafe(prop.RetType); + CheckUnsafe(prop.RetType); } } @@ -1080,10 +984,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return null; } - throw ErrorContext.Error(ErrorCode.ERR_ObjectProhibited, swt); + throw ErrorHandling.Error(ErrorCode.ERR_ObjectProhibited, swt); } - throw ErrorContext.Error(ErrorCode.ERR_ObjectRequired, swt); + throw ErrorHandling.Error(ErrorCode.ERR_ObjectRequired, swt); } // At this point, all errors for static invocations have been reported, and @@ -1125,7 +1029,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } ///////////////////////////////////////////////////////////////////////////////// - private bool IsMatchingStatic(SymWithType swt, Expr pObject) + private static bool IsMatchingStatic(SymWithType swt, Expr pObject) { Symbol pSym = swt.Sym; @@ -1163,7 +1067,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // this determines whether the expression as an pObject of a prop or field is an // lvalue [Conditional("DEBUG")] - private void AssertObjectIsLvalue(Expr pObject) + private static void AssertObjectIsLvalue(Expr pObject) { Debug.Assert ( pObject == null || // statics are always lvalues @@ -1195,7 +1099,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics newArgs = null; Expr newArgsTail = null; - MethodOrPropertySymbol mostDerivedMethod = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mp, callingObjectType); + MethodOrPropertySymbol mostDerivedMethod = GroupToArgsBinder.FindMostDerivedMethod(mp, callingObjectType); int paramCount = mp.Params.Count; TypeArray @params = mp.Params; @@ -1224,7 +1128,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (paramCount != 0) paramCount--; - GetExprFactory().AppendItemToList(indir, ref newArgs, ref newArgsTail); + ExprFactory.AppendItemToList(indir, ref newArgs, ref newArgsTail); } else if (paramCount != 0) { @@ -1251,7 +1155,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(index != mp.Params.Count); - CType substDestType = GetTypes().SubstType(@params[index], type, pTypeArgs); + CType substDestType = TypeManager.SubstType(@params[index], type, pTypeArgs); // If we cant convert the argument and we're the param array argument, then deal with it. if (!canConvert(named.Value, substDestType) && @@ -1265,10 +1169,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // void Foo(int y, params int[] x); // ... // Foo(x:1, y:1); - CType arrayType = (ArrayType)GetTypes().SubstType(mp.Params[mp.Params.Count - 1], type, pTypeArgs); + CType arrayType = (ArrayType)TypeManager.SubstType(mp.Params[mp.Params.Count - 1], type, pTypeArgs); // Use an EK_ARRINIT even in the empty case so empty param arrays in attributes work. - ExprArrayInit arrayInit = GetExprFactory().CreateArrayInit(arrayType, null, null, new[] { 0 }, 1); + ExprArrayInit arrayInit = ExprFactory.CreateArrayInit(arrayType, null, null, new[] { 0 }, 1); arrayInit.GeneratedForParamArray = true; arrayInit.OptionalArguments = named.Value; @@ -1284,7 +1188,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } else { - CType substDestType = GetTypes().SubstType(@params[iDst], type, pTypeArgs); + CType substDestType = TypeManager.SubstType(@params[iDst], type, pTypeArgs); rval = tryConvert(indir, substDestType); } @@ -1306,7 +1210,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(rval != null); indir = rval; - GetExprFactory().AppendItemToList(rval, ref newArgs, ref newArgsTail); + ExprFactory.AppendItemToList(rval, ref newArgs, ref newArgsTail); paramCount--; } // note that destype might not be valid if we are in varargs, but then we won't ever use it... @@ -1332,7 +1236,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } // we need to create an array and put it as the last arg... - CType substitutedArrayType = GetTypes().SubstType(mp.Params[mp.Params.Count - 1], type, pTypeArgs); + CType substitutedArrayType = TypeManager.SubstType(mp.Params[mp.Params.Count - 1], type, pTypeArgs); if (!(substitutedArrayType is ArrayType subArr) || !subArr.IsSZArray) { // Invalid type for params array parameter. Happens in LAF scenarios, e.g. @@ -1346,7 +1250,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType elementType = subArr.ElementType; // Use an EK_ARRINIT even in the empty case so empty param arrays in attributes work. - ExprArrayInit exprArrayInit = GetExprFactory().CreateArrayInit(substitutedArrayType, null, null, new[] { 0 }, 1); + ExprArrayInit exprArrayInit = ExprFactory.CreateArrayInit(substitutedArrayType, null, null, new[] { 0 }, 1); exprArrayInit.GeneratedForParamArray = true; if (it.AtEnd()) @@ -1360,9 +1264,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } else { - argsPtr = GetExprFactory().CreateList(argsPtr, exprArrayInit); + argsPtr = ExprFactory.CreateList(argsPtr, exprArrayInit); } - GetExprFactory().AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); + ExprFactory.AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); } else { @@ -1384,13 +1288,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { expr = tryConvert(expr, elementType); } - GetExprFactory().AppendItemToList(expr, ref newList, ref newListTail); + ExprFactory.AppendItemToList(expr, ref newList, ref newListTail); } exprArrayInit.DimensionSize = count; exprArrayInit.DimensionSizes[0] = count; exprArrayInit.OptionalArguments = newList; - GetExprFactory().AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); + ExprFactory.AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); } } @@ -1426,7 +1330,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GetPredefindType(PredefinedType.PT_INT); } - internal void FillInArgInfoFromArgList(ArgInfos argInfo, Expr args) + internal static void FillInArgInfoFromArgList(ArgInfos argInfo, Expr args) { CType[] prgtype = new CType[argInfo.carg]; argInfo.prgexpr = new List(); @@ -1454,10 +1358,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(iarg <= argInfo.carg); - argInfo.types = GetGlobalSymbols().AllocParams(iarg, prgtype); + argInfo.types = TypeArray.Allocate(prgtype); } - private bool TryGetExpandedParams(TypeArray @params, int count, out TypeArray ppExpandedParams) + private static bool TryGetExpandedParams(TypeArray @params, int count, out TypeArray ppExpandedParams) { CType[] prgtype; if (count < @params.Count - 1) @@ -1467,7 +1371,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // case that all the parameters are optional. prgtype = new CType[@params.Count - 1]; @params.CopyItems(0, @params.Count - 1, prgtype); - ppExpandedParams = GetGlobalSymbols().AllocParams(@params.Count - 1, prgtype); + ppExpandedParams = TypeArray.Allocate(prgtype); return true; } @@ -1491,7 +1395,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics prgtype[itype] = elementType; } - ppExpandedParams = GetGlobalSymbols().AllocParams(prgtype); + ppExpandedParams = TypeArray.Allocate(prgtype); return true; } @@ -1504,7 +1408,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return (!sym.isOverride || sym.isHideByName) && (!requireUC || sym.isUserCallable()); } - private bool isConvInTable(List convTable, MethodSymbol meth, AggregateType ats, bool fSrc, bool fDst) + private static bool IsConvInTable(List convTable, MethodSymbol meth, AggregateType ats, bool fSrc, bool fDst) { foreach (UdConvInfo conv in convTable) { @@ -1516,6 +1420,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } } + return false; } @@ -1717,35 +1622,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics PredefinedName.PN_OPRIGHTSHIFT, }; - private Name ekName(ExpressionKind ek) + private static Name ExpressionKindName(ExpressionKind ek) { Debug.Assert(ek >= ExpressionKind.FirstOp && (ek - ExpressionKind.FirstOp) < (int)s_EK2NAME.Length); return NameManager.GetPredefinedName(s_EK2NAME[ek - ExpressionKind.FirstOp]); } - private void checkUnsafe(CType type) + private static void CheckUnsafe(CType type) { if (type == null || type.IsUnsafe()) { - throw ErrorContext.Error(ErrorCode.ERR_UnsafeNeeded); + throw ErrorHandling.Error(ErrorCode.ERR_UnsafeNeeded); } } - //////////////////////////////////////////////////////////////////////////////// - private AggregateDeclaration ContextForMemberLookup() - { - return Context.ContextForMemberLookup; - } + private AggregateSymbol ContextForMemberLookup => Context.ContextForMemberLookup; - private ExprWrap WrapShortLivedExpression(Expr expr) - { - return GetExprFactory().CreateWrap(expr); - } + private static ExprWrap WrapShortLivedExpression(Expr expr) => ExprFactory.CreateWrap(expr); - private ExprAssignment GenerateOptimizedAssignment(Expr op1, Expr op2) - { - return GetExprFactory().CreateAssignment(op1, op2); - } + private static ExprAssignment GenerateOptimizedAssignment(Expr op1, Expr op2) => ExprFactory.CreateAssignment(op1, op2); internal static int CountArguments(Expr args) { diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GlobalSymbolContext.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GlobalSymbolContext.cs deleted file mode 100644 index 5648093..0000000 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GlobalSymbolContext.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CSharp.RuntimeBinder.Syntax; - -namespace Microsoft.CSharp.RuntimeBinder.Semantics -{ - /***************************************************************************** - A GlobalSymbolContext represents the global symbol tables for a compilation. - This includes symbols, types, declarations. - *****************************************************************************/ - - internal sealed class GlobalSymbolContext - { - private readonly PredefinedTypes _predefTypes; - - public GlobalSymbolContext() - { - GlobalSymbols = new BSYMMGR(); - _predefTypes = new PredefinedTypes(GlobalSymbols); - TypeManager = new TypeManager(GlobalSymbols, _predefTypes); - } - - public TypeManager TypeManager { get; } - public TypeManager GetTypes() { return TypeManager; } - private BSYMMGR GlobalSymbols { get; } - public BSYMMGR GetGlobalSymbols() { return GlobalSymbols; } - public PredefinedTypes GetPredefTypes() { return _predefTypes; } - - public SymFactory GetGlobalSymbolFactory() - { - return GetGlobalSymbols().GetSymFactory(); - } - } -} diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs index 2303fef..aa9ccbd 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinder.cs @@ -16,7 +16,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // to the best applicable method in the group. // ---------------------------------------------------------------------------- - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { internal sealed class GroupToArgsBinder { @@ -60,7 +60,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public GroupToArgsBinder(ExpressionBinder exprBinder, BindingFlag bindFlags, ExprMemberGroup grp, ArgInfos args, ArgInfos originalArgs, NamedArgumentsKind namedArgumentsKind) { Debug.Assert(grp != null); - Debug.Assert(exprBinder != null); Debug.Assert(args != null); _pExprBinder = exprBinder; @@ -100,28 +99,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - public GroupToArgsBinderResult GetResultsOfBind() - { - return _results; - } + public GroupToArgsBinderResult GetResultsOfBind() => _results; - private SymbolLoader GetSymbolLoader() - { - return _pExprBinder.GetSymbolLoader(); - } - private CSemanticChecker GetSemanticChecker() - { - return _pExprBinder.GetSemanticChecker(); - } - private ErrorHandling GetErrorContext() - { - return _pExprBinder.GetErrorContext(); - } private static CType GetTypeQualifier(ExprMemberGroup pGroup) { Debug.Assert(pGroup != null); - return (pGroup.Flags & EXPRFLAG.EXF_CTOR) != 0 ? pGroup.ParentType : pGroup.OptionalObject?.Type; } @@ -137,7 +120,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // iterator will only return propsyms (or methsyms, or whatever) symbmask_t mask = (symbmask_t)(1 << (int)_pGroup.SymKind); - CMemberLookupResults.CMethodIterator iterator = _pGroup.MemberLookupResults.GetMethodIterator(GetSemanticChecker(), GetSymbolLoader(), GetTypeQualifier(_pGroup), _pExprBinder.ContextForMemberLookup(), _pGroup.TypeArgs.Count, _pGroup.Flags, mask, _namedArgumentsKind == NamedArgumentsKind.NonTrailing ? _pOriginalArguments : null); + CMemberLookupResults.CMethodIterator iterator = _pGroup.MemberLookupResults.GetMethodIterator(GetTypeQualifier(_pGroup), _pExprBinder.ContextForMemberLookup, _pGroup.TypeArgs.Count, _pGroup.Flags, mask, _namedArgumentsKind == NamedArgumentsKind.NonTrailing ? _pOriginalArguments : null); while (true) { bool bFoundExpanded; @@ -292,7 +275,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } // Mark object. - AggregateType typeObject = GetSymbolLoader().GetPredefindType(PredefinedType.PT_OBJECT); + AggregateType typeObject = SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT); _HiddenTypes.Add(typeObject); } } @@ -311,7 +294,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - private void CopyArgInfos(ArgInfos src, ArgInfos dst) + private static void CopyArgInfos(ArgInfos src, ArgInfos dst) { dst.carg = src.carg; dst.types = src.types; @@ -349,11 +332,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics pAmbig1.mpwi.GetType() != pAmbig2.mpwi.GetType() || pAmbig1.mpwi.MethProp().Params == pAmbig2.mpwi.MethProp().Params) { - throw GetErrorContext().Error(ErrorCode.ERR_AmbigCall, pAmbig1.mpwi, pAmbig2.mpwi); + throw ErrorHandling.Error(ErrorCode.ERR_AmbigCall, pAmbig1.mpwi, pAmbig2.mpwi); } // The two signatures are identical so don't use the type args in the error message. - throw GetErrorContext().Error(ErrorCode.ERR_AmbigCall, pAmbig1.mpwi.MethProp(), pAmbig2.mpwi.MethProp()); + throw ErrorHandling.Error(ErrorCode.ERR_AmbigCall, pAmbig1.mpwi.MethProp(), pAmbig2.mpwi.MethProp()); } } @@ -407,26 +390,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } _bArgumentsChangedForNamedOrOptionalArguments = ReOrderArgsForNamedArguments( - methprop, - _pCurrentParameters, - _pCurrentType, - _pGroup, - _pArguments, - _pExprBinder.GetTypes(), - _pExprBinder.GetExprFactory(), - GetSymbolLoader()); + methprop, _pCurrentParameters, _pCurrentType, _pGroup, _pArguments); return _bArgumentsChangedForNamedOrOptionalArguments; } internal static bool ReOrderArgsForNamedArguments( - MethodOrPropertySymbol methprop, - TypeArray pCurrentParameters, - AggregateType pCurrentType, - ExprMemberGroup pGroup, - ArgInfos pArguments, - TypeManager typeManager, - ExprFactory exprFactory, - SymbolLoader symbolLoader) + MethodOrPropertySymbol methprop, TypeArray pCurrentParameters, AggregateType pCurrentType, ExprMemberGroup pGroup, ArgInfos pArguments) { // We use the param count from pCurrentParameters because they may have been resized // for param arrays. @@ -438,7 +407,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // set, then for the remainder, look for a named argument with a matching name. int index = 0; Expr paramArrayArgument = null; - TypeArray @params = typeManager.SubstTypeArray( + TypeArray @params = TypeManager.SubstTypeArray( pCurrentParameters, pCurrentType, pGroup.TypeArgs); @@ -477,7 +446,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (methprop.IsParameterOptional(index)) { - pNewArg = GenerateOptionalArgument(symbolLoader, exprFactory, methprop, @params[index], index); + pNewArg = GenerateOptionalArgument(methprop, @params[index], index); } else if (paramArrayArgument != null && index == methprop.Params.Count - 1) { @@ -508,18 +477,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics prgTypes[i] = pArguments.prgexpr[i].Type; } pArguments.carg = pCurrentParameters.Count; - pArguments.types = symbolLoader.getBSymmgr().AllocParams(pCurrentParameters.Count, prgTypes); + pArguments.types = TypeArray.Allocate(prgTypes); return true; } ///////////////////////////////////////////////////////////////////////////////// - private static Expr GenerateOptionalArgument( - SymbolLoader symbolLoader, - ExprFactory exprFactory, - MethodOrPropertySymbol methprop, - CType type, - int index) + private static Expr GenerateOptionalArgument(MethodOrPropertySymbol methprop, CType type, int index) { CType pParamType = type; CType pRawParamType = type.StripNubs(); @@ -536,8 +500,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // This is the specific case where we want to create a DateTime // but the constval that stores it is a long. - AggregateType dateTimeType = symbolLoader.GetPredefindType(PredefinedType.PT_DATETIME); - optionalArgument = exprFactory.CreateConstant(dateTimeType, ConstVal.Get(DateTime.FromBinary(cv.Int64Val))); + AggregateType dateTimeType = SymbolLoader.GetPredefindType(PredefinedType.PT_DATETIME); + optionalArgument = ExprFactory.CreateConstant(dateTimeType, ConstVal.Get(DateTime.FromBinary(cv.Int64Val))); } else if (pConstValType.IsSimpleOrEnumOrString) { @@ -548,7 +512,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // For enum parameters, we create a constant of the enum type. For everything // else, we create the appropriate constant. - optionalArgument = exprFactory.CreateConstant( + optionalArgument = ExprFactory.CreateConstant( pRawParamType.IsEnumType && pConstValType == pRawParamType.UnderlyingEnumType ? pRawParamType : pConstValType, @@ -558,7 +522,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // We have an "= null" default value with a reference type or a nullable type. - optionalArgument = exprFactory.CreateNull(); + optionalArgument = ExprFactory.CreateNull(); } else { @@ -566,7 +530,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // interpreted as default(something). For instance, the pParamType could be // a type parameter type or a non-simple value type. - optionalArgument = exprFactory.CreateZeroInit(pParamType); + optionalArgument = ExprFactory.CreateZeroInit(pParamType); } } else @@ -581,18 +545,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // For [opt] parameters of type object, if we have marshal(iunknown), // marshal(idispatch), or marshal(interface), then we emit a null. - optionalArgument = exprFactory.CreateNull(); + optionalArgument = ExprFactory.CreateNull(); } else { // Otherwise, we generate Type.Missing - AggregateSymbol agg = symbolLoader.GetPredefAgg(PredefinedType.PT_MISSING); + AggregateSymbol agg = SymbolLoader.GetPredefAgg(PredefinedType.PT_MISSING); Name name = NameManager.GetPredefinedName(PredefinedName.PN_CAP_VALUE); - FieldSymbol field = symbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol) as FieldSymbol; + FieldSymbol field = SymbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol) as FieldSymbol; FieldWithType fwt = new FieldWithType(field, agg.getThisType()); - ExprField exprField = exprFactory.CreateField(agg.getThisType(), null, fwt); - optionalArgument = exprFactory.CreateCast(type, exprField); + ExprField exprField = ExprFactory.CreateField(agg.getThisType(), null, fwt); + optionalArgument = ExprFactory.CreateCast(type, exprField); } } else @@ -600,7 +564,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Every type aside from object that doesn't have a default value gets // its default value. - optionalArgument = exprFactory.CreateZeroInit(pParamType); + optionalArgument = ExprFactory.CreateZeroInit(pParamType); } } @@ -609,21 +573,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return optionalArgument; } - ///////////////////////////////////////////////////////////////////////////////// - - private MethodOrPropertySymbol FindMostDerivedMethod( - MethodOrPropertySymbol pMethProp, - Expr pObject) - { - return FindMostDerivedMethod(GetSymbolLoader(), pMethProp, pObject?.Type); - } - - ///////////////////////////////////////////////////////////////////////////////// + private static MethodOrPropertySymbol FindMostDerivedMethod(MethodOrPropertySymbol pMethProp, Expr pObject) => + FindMostDerivedMethod(pMethProp, pObject?.Type); - public static MethodOrPropertySymbol FindMostDerivedMethod( - SymbolLoader symbolLoader, - MethodOrPropertySymbol pMethProp, - CType pType) + public static MethodOrPropertySymbol FindMostDerivedMethod(MethodOrPropertySymbol pMethProp, CType pType) { bool bIsIndexer = false; @@ -662,9 +615,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics pAggregate?.GetBaseAgg() != null; pAggregate = pAggregate.GetBaseAgg()) { - for (MethodOrPropertySymbol meth = symbolLoader.LookupAggMember(method.name, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol) as MethodOrPropertySymbol; + for (MethodOrPropertySymbol meth = SymbolLoader.LookupAggMember(method.name, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol) as MethodOrPropertySymbol; meth != null; - meth = SymbolLoader.LookupNextSym(meth, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol) as MethodOrPropertySymbol) + meth = meth.LookupNext(symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol) as MethodOrPropertySymbol) { if (!meth.isOverride) { @@ -726,7 +679,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // just generate defaults for every missing argument. int i = _pArguments.carg; int index = 0; - TypeArray @params = _pExprBinder.GetTypes().SubstTypeArray( + TypeArray @params = TypeManager.SubstTypeArray( _pCurrentParameters, _pCurrentType, _pGroup.TypeArgs); @@ -739,7 +692,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - pArguments[index] = GenerateOptionalArgument(GetSymbolLoader(), _pExprBinder.GetExprFactory(), methprop, @params[i], i); + pArguments[index] = GenerateOptionalArgument(methprop, @params[i], i); } // Success. Lets copy them in now. @@ -752,7 +705,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { prgTypes[n] = _pArguments.prgexpr[n].Type; } - _pArguments.types = GetSymbolLoader().getBSymmgr().AllocParams(@params.Count, prgTypes); + _pArguments.types = TypeArray.Allocate(prgTypes); _pArguments.carg = @params.Count; _bArgumentsChangedForNamedOrOptionalArguments = true; return true; @@ -905,7 +858,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(_methList.IsEmpty() || _methList.Head().mpwi.MethProp() != _pCurrentSym); // Construct the expanded params. - return _pExprBinder.TryGetExpandedParams(_pCurrentSym.Params, _pArguments.carg, out _pCurrentParameters); + return TryGetExpandedParams(_pCurrentSym.Params, _pArguments.carg, out _pCurrentParameters); } private Result DetermineCurrentTypeArgs() @@ -932,8 +885,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // error sym to go to any type. bool inferenceSucceeded = MethodTypeInferrer.Infer( - _pExprBinder, GetSymbolLoader(), methSym, _pCurrentParameters, _pArguments, - out _pCurrentTypeArgs); + _pExprBinder, methSym, _pCurrentParameters, _pArguments, out _pCurrentTypeArgs); if (!inferenceSucceeded) { @@ -968,7 +920,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics for (int ivar = 0; ivar < _pArguments.carg; ivar++) { CType var = _pCurrentParameters[ivar]; - bool constraintErrors = !TypeBind.CheckConstraints(GetSemanticChecker(), GetErrorContext(), var, CheckConstraintsFlags.NoErrors); + bool constraintErrors = !TypeBind.CheckConstraints(var, CheckConstraintsFlags.NoErrors); if (constraintErrors && !DoesTypeArgumentsContainErrorSym(var)) { _mpwiParamTypeConstraints.Set(_pCurrentSym, _pCurrentType, _pCurrentTypeArgs); @@ -1048,7 +1000,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Parameter types might have changed as a result of // method type inference. - _pCurrentParameters = _pExprBinder.GetTypes().SubstTypeArray( + _pCurrentParameters = TypeManager.SubstTypeArray( _pCurrentParameters, _pCurrentType, _pCurrentTypeArgs); // It is also possible that an optional argument has changed its value @@ -1086,12 +1038,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(pMethod != null); } Debug.Assert(pMethod.IsParameterOptional(iParam)); - Expr pArgumentNew = GenerateOptionalArgument(GetSymbolLoader(), _pExprBinder.GetExprFactory(), pMethod, _pCurrentParameters[iParam], iParam); + Expr pArgumentNew = GenerateOptionalArgument(pMethod, _pCurrentParameters[iParam], iParam); _pArguments.prgexpr[iParam] = pArgumentNew; } } - private bool DoesTypeArgumentsContainErrorSym(CType var) + private static bool DoesTypeArgumentsContainErrorSym(CType var) { if (!(var is AggregateType varAgg)) { @@ -1135,7 +1087,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_results.BestResult.TypeArgs.Count > 0) { // Check method type variable constraints. - TypeBind.CheckMethConstraints(GetSemanticChecker(), GetErrorContext(), new MethWithInst(_results.BestResult)); + TypeBind.CheckMethConstraints(new MethWithInst(_results.BestResult)); } } } @@ -1145,7 +1097,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // First and foremost, report if the user specified a name more than once. if (_pDuplicateSpecifiedName != null) { - return GetErrorContext().Error(ErrorCode.ERR_DuplicateNamedArgument, _pDuplicateSpecifiedName); + return ErrorHandling.Error(ErrorCode.ERR_DuplicateNamedArgument, _pDuplicateSpecifiedName); } Debug.Assert(_methList.IsEmpty()); @@ -1153,7 +1105,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_results.InaccessibleResult) { // We might have called this, but it is inaccessible... - return GetSemanticChecker().ReportAccessError(_results.InaccessibleResult, _pExprBinder.ContextForMemberLookup(), GetTypeQualifier(_pGroup)); + return CSemanticChecker.ReportAccessError(_results.InaccessibleResult, _pExprBinder.ContextForMemberLookup, GetTypeQualifier(_pGroup)); } if (_misnamed) @@ -1178,7 +1130,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // We have the bad name. Is it misplaced or absent? if (paramNames.Contains(name)) { - return GetErrorContext().Error(ErrorCode.ERR_BadNonTrailingNamedArgument, name); + return ErrorHandling.Error(ErrorCode.ERR_BadNonTrailingNamedArgument, name); } // Let this be handled by _pInvalidSpecifiedName handling. @@ -1191,7 +1143,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics else if (_mpwiBogus) { // We might have called this, but it is bogus... - return GetErrorContext().Error(ErrorCode.ERR_BindToBogus, _mpwiBogus); + return ErrorHandling.Error(ErrorCode.ERR_BindToBogus, _mpwiBogus); } bool bUseDelegateErrors = false; @@ -1224,19 +1176,19 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(_results.UninferableResult.Sym is MethodSymbol); MethWithType mwtCantInfer = new MethWithType(_results.UninferableResult.Meth(), _results.UninferableResult.GetType()); - return GetErrorContext().Error(ErrorCode.ERR_CantInferMethTypeArgs, mwtCantInfer); + return ErrorHandling.Error(ErrorCode.ERR_CantInferMethTypeArgs, mwtCantInfer); } if (_mwtBadArity) { int cvar = _mwtBadArity.Meth().typeVars.Count; - return GetErrorContext().Error(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _mwtBadArity, new ErrArgSymKind(_mwtBadArity.Meth()), _pArguments.carg); + return ErrorHandling.Error(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _mwtBadArity, new ErrArgSymKind(_mwtBadArity.Meth()), _pArguments.carg); } if (_mpwiParamTypeConstraints) { // This will always report an error - TypeBind.CheckMethConstraints(GetSemanticChecker(), GetErrorContext(), new MethWithInst(_mpwiParamTypeConstraints)); + TypeBind.CheckMethConstraints(new MethWithInst(_mpwiParamTypeConstraints)); Debug.Fail("Unreachable"); return null; } @@ -1245,37 +1197,37 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Give a better message for delegate invoke. return _pGroup.OptionalObject?.Type is AggregateType agg && agg.OwningAggregate.IsDelegate() - ? GetErrorContext().Error( + ? ErrorHandling.Error( ErrorCode.ERR_BadNamedArgumentForDelegateInvoke, agg.OwningAggregate.name, _pInvalidSpecifiedName) - : GetErrorContext().Error(ErrorCode.ERR_BadNamedArgument, _pGroup.Name, _pInvalidSpecifiedName); + : ErrorHandling.Error(ErrorCode.ERR_BadNamedArgument, _pGroup.Name, _pInvalidSpecifiedName); } if (_pNameUsedInPositionalArgument != null) { - return GetErrorContext().Error(ErrorCode.ERR_NamedArgumentUsedInPositional, _pNameUsedInPositionalArgument); + return ErrorHandling.Error(ErrorCode.ERR_NamedArgumentUsedInPositional, _pNameUsedInPositionalArgument); } // The number of arguments must be wrong. if (_fCandidatesUnsupported) { - return GetErrorContext().Error(ErrorCode.ERR_BindToBogus, nameErr); + return ErrorHandling.Error(ErrorCode.ERR_BindToBogus, nameErr); } if (bUseDelegateErrors) { Debug.Assert(0 == (_pGroup.Flags & EXPRFLAG.EXF_CTOR)); - return GetErrorContext().Error(ErrorCode.ERR_BadDelArgCount, nameErr, _pArguments.carg); + return ErrorHandling.Error(ErrorCode.ERR_BadDelArgCount, nameErr, _pArguments.carg); } if (0 != (_pGroup.Flags & EXPRFLAG.EXF_CTOR)) { Debug.Assert(!(_pGroup.ParentType is TypeParameterType)); - return GetErrorContext().Error(ErrorCode.ERR_BadCtorArgCount, _pGroup.ParentType, _pArguments.carg); + return ErrorHandling.Error(ErrorCode.ERR_BadCtorArgCount, _pGroup.ParentType, _pArguments.carg); } - return GetErrorContext().Error(ErrorCode.ERR_BadArgCount, nameErr, _pArguments.carg); + return ErrorHandling.Error(ErrorCode.ERR_BadArgCount, nameErr, _pArguments.carg); } private RuntimeBinderException ReportErrorsForBestMatching(bool bUseDelegateErrors) @@ -1283,10 +1235,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (bUseDelegateErrors) { // Point to the Delegate, not the Invoke method - return GetErrorContext().Error(ErrorCode.ERR_BadDelArgTypes, _results.BestResult.GetType()); + return ErrorHandling.Error(ErrorCode.ERR_BadDelArgTypes, _results.BestResult.GetType()); } - return GetErrorContext().Error(ErrorCode.ERR_BadArgTypes, _results.BestResult); + return ErrorHandling.Error(ErrorCode.ERR_BadArgTypes, _results.BestResult); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinderResult.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinderResult.cs index 1ef08e3..2e5b417 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinderResult.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/GroupToArgsBinderResult.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { // ---------------------------------------------------------------------------- // This class takes an EXPRMEMGRP and a set of arguments and binds the arguments diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs index 72458c3..17269e4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ImplicitConversion.cs @@ -7,7 +7,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { // ---------------------------------------------------------------------------- // BindImplicitConversion @@ -191,7 +191,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics object srcRuntimeObject = _exprSrc?.RuntimeObject; if (srcRuntimeObject != null && _typeDest.AssociatedSystemType.IsInstanceOfType(srcRuntimeObject) - && _binder.GetSemanticChecker().CheckTypeAccess(_typeDest, _binder.Context.ContextForMemberLookup)) + && CSemanticChecker.CheckTypeAccess(_typeDest, _binder.Context.ContextForMemberLookup)) { if (_needsExprDest) { @@ -270,7 +270,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics AggregateType atsDst = nubDst.GetAts(); // Check for the unboxing conversion. This takes precedence over the wrapping conversions. - if (GetSymbolLoader().HasBaseConversion(nubDst.UnderlyingType, _typeSrc) && !CConversions.FWrappingConv(_typeSrc, nubDst)) + if (SymbolLoader.HasBaseConversion(nubDst.UnderlyingType, _typeSrc) && !CConversions.FWrappingConv(_typeSrc, nubDst)) { // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable. Debug.Assert(atsDst != _typeSrc); @@ -310,8 +310,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_needsExprDest) { _exprDest = _exprSrc is ExprConstant - ? GetExprFactory().CreateZeroInit(nubDst) - : GetExprFactory().CreateCast(_typeDest, _exprSrc); + ? ExprFactory.CreateZeroInit(nubDst) + : ExprFactory.CreateCast(_typeDest, _exprSrc); } return true; } @@ -331,7 +331,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (dstWasNullable) { - ExprCall call = _binder.BindNubNew(exprTmp); + ExprCall call = BindNubNew(exprTmp); exprTmp = call; call.NullableCallLiftKind = NullableCallLiftKind.NullableConversionConstructor; } @@ -363,8 +363,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_needsExprDest) { MethWithInst mwi = new MethWithInst(null, null); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall exprDst = GetExprFactory().CreateCall(0, nubDst, _exprSrc, pMemGroup, null); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall exprDst = ExprFactory.CreateCall(0, nubDst, _exprSrc, pMemGroup, null); // Here we want to first check whether or not the conversions work on the base types. @@ -408,8 +408,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Otherwise, bind this as a cast to the destination type. In a later // rewrite pass we will rewrite the cast as SEQ(side effects, ZEROINIT). _exprDest = _exprSrc is ExprConstant - ? GetExprFactory().CreateZeroInit(_typeDest) - : GetExprFactory().CreateCast(_typeDest, _exprSrc); + ? ExprFactory.CreateZeroInit(_typeDest) + : ExprFactory.CreateCast(_typeDest, _exprSrc); } return true; } @@ -440,7 +440,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } return true; } - if (GetSymbolLoader().HasBaseConversion(nubSrc.UnderlyingType, _typeDest) && !CConversions.FUnwrappingConv(nubSrc, _typeDest)) + if (SymbolLoader.HasBaseConversion(nubSrc.UnderlyingType, _typeDest) && !CConversions.FUnwrappingConv(nubSrc, _typeDest)) { if (_needsExprDest) { @@ -475,7 +475,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // * From any array-type to System.Array. // * From any array-type to any interface implemented by System.Array. - if (!GetSymbolLoader().HasBaseConversion(_typeSrc, _typeDest)) + if (!SymbolLoader.HasBaseConversion(_typeSrc, _typeDest)) { return false; } @@ -571,7 +571,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // * From any delegate-type to System.Delegate. // * From any delegate-type to System.ICloneable. - if (!(_typeDest is AggregateType) || !GetSymbolLoader().HasBaseConversion(pSource, _typeDest)) + if (!(_typeDest is AggregateType) || !SymbolLoader.HasBaseConversion(pSource, _typeDest)) { return false; } @@ -601,7 +601,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // base class for all enums (21.4). A struct or enum can be boxed to the type System.ValueType, // since that is the direct base class for all structs (18.3.2) and a base class for all enums. - if (_typeDest is AggregateType aggDest && GetSymbolLoader().HasBaseConversion(aggTypeSrc, aggDest)) + if (_typeDest is AggregateType aggDest && SymbolLoader.HasBaseConversion(aggTypeSrc, aggDest)) { if (_needsExprDest) _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_BOX | EXPRFLAG.EXF_CANTBENULL); @@ -648,7 +648,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // into a constant here - we should move this to a later pass. if (_needsExprDest) { - _exprDest = GetExprFactory().CreateConstant(_typeDest, ConstVal.GetDefaultValue(_typeDest.ConstValKind)); + _exprDest = ExprFactory.CreateConstant(_typeDest, ConstVal.GetDefaultValue(_typeDest.ConstValKind)); } return true; } @@ -730,15 +730,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest); return true; } - - private SymbolLoader GetSymbolLoader() - { - return _binder.GetSymbolLoader(); - } - private ExprFactory GetExprFactory() - { - return _binder.GetExprFactory(); - } } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookup.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookup.cs index a17e13c..53a477a 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookup.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookup.cs @@ -38,8 +38,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal sealed class MemberLookup { // The inputs to Lookup. - private CSemanticChecker _pSemanticChecker; - private SymbolLoader _pSymbolLoader; private CType _typeSrc; private CType _typeQual; private ParentSymbol _symWhere; @@ -106,15 +104,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Make sure this type is accessible. It may not be due to private inheritance // or friend assemblies. - bool fInaccess = !GetSemanticChecker().CheckTypeAccess(typeCur, _symWhere); + bool fInaccess = !CSemanticChecker.CheckTypeAccess(typeCur, _symWhere); if (fInaccess && (_csym != 0 || _swtInaccess != null)) return false; // Loop through symbols. Symbol symCur; - for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.OwningAggregate, symbmask_t.MASK_Member); + for (symCur = SymbolLoader.LookupAggMember(_name, typeCur.OwningAggregate, symbmask_t.MASK_Member); symCur != null; - symCur = SymbolLoader.LookupNextSym(symCur, typeCur.OwningAggregate, symbmask_t.MASK_Member)) + symCur = symCur.LookupNext(symbmask_t.MASK_Member)) { Debug.Assert(!(symCur is AggregateSymbol)); // Check for arity. @@ -158,7 +156,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - if (fInaccess || !GetSemanticChecker().CheckAccess(symCur, typeCur, _symWhere, _typeQual)) + if (fInaccess || !CSemanticChecker.CheckAccess(symCur, typeCur, _symWhere, _typeQual)) { // Not accessible so get the next sym. if (!_swtInaccess) @@ -310,7 +308,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - private bool IsDynamicMember(Symbol sym) + private static bool IsDynamicMember(Symbol sym) { System.Runtime.CompilerServices.DynamicAttribute da = null; if (sym is FieldSymbol field) @@ -470,27 +468,23 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - private SymbolLoader GetSymbolLoader() { return _pSymbolLoader; } - private CSemanticChecker GetSemanticChecker() { return _pSemanticChecker; } - private ErrorHandling GetErrorContext() { return GetSymbolLoader().GetErrorContext(); } - - private RuntimeBinderException ReportBogus(SymWithType swt) + private static RuntimeBinderException ReportBogus(SymWithType swt) { Debug.Assert(CSemanticChecker.CheckBogus(swt.Sym)); MethodSymbol meth1 = swt.Prop().GetterMethod; MethodSymbol meth2 = swt.Prop().SetterMethod; Debug.Assert((meth1 ?? meth2) != null); return meth1 == null | meth2 == null - ? GetErrorContext().Error( + ? ErrorHandling.Error( ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 ?? meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym)) - : GetErrorContext().Error( + : ErrorHandling.Error( ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()), new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym)); } - private bool IsDelegateType(CType pSrcType, AggregateType pAggType) => - GetSymbolLoader().GetTypeManager().SubstType(pSrcType, pAggType, pAggType.TypeArgsAll).IsDelegateType; + private static bool IsDelegateType(CType pSrcType, AggregateType pAggType) => + TypeManager.SubstType(pSrcType, pAggType, pAggType.TypeArgsAll).IsDelegateType; ///////////////////////////////////////////////////////////////////////////////// // Public methods. @@ -524,18 +518,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics flags - See MemLookFlags. TypeVarsAllowed only applies to the most derived type (not base types). ***************************************************************************************************/ - public bool Lookup(CSemanticChecker checker, CType typeSrc, Expr obj, ParentSymbol symWhere, Name name, int arity, MemLookFlags flags) + public bool Lookup(CType typeSrc, Expr obj, ParentSymbol symWhere, Name name, int arity, MemLookFlags flags) { Debug.Assert((flags & ~MemLookFlags.All) == 0); Debug.Assert(obj == null || obj.Type != null); Debug.Assert(typeSrc is AggregateType); - Debug.Assert(checker != null); _prgtype = _rgtypeStart; // Save the inputs for error handling, etc. - _pSemanticChecker = checker; - _pSymbolLoader = checker.SymbolLoader; _typeSrc = typeSrc; _symWhere = symWhere; _name = name; @@ -545,29 +536,27 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics _typeQual = (_flags & MemLookFlags.Ctor) != 0 ? _typeSrc : obj?.Type; // Determine what to search. - AggregateType typeCls1 = null; - AggregateType typeIface = null; - TypeArray ifaces = BSYMMGR.EmptyTypeArray(); - AggregateType typeCls2 = null; - - if (!typeSrc.IsInterfaceType) - { - typeCls1 = (AggregateType)typeSrc; + AggregateType typeCls1; + AggregateType typeIface; + TypeArray ifaces; - if (typeCls1.IsWindowsRuntimeType) - { - ifaces = typeCls1.GetWinRTCollectionIfacesAll(GetSymbolLoader()); - } - } - else + if (typeSrc.IsInterfaceType) { Debug.Assert((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall)) == 0); + typeCls1 = null; typeIface = (AggregateType)typeSrc; ifaces = typeIface.IfacesAll; } + else + { + typeCls1 = (AggregateType)typeSrc; + typeIface = null; + ifaces = typeCls1.IsWindowsRuntimeType ? typeCls1.WinRTCollectionIfacesAll : TypeArray.Empty; + } - if (typeIface != null || ifaces.Count > 0) - typeCls2 = GetSymbolLoader().GetPredefindType(PredefinedType.PT_OBJECT); + AggregateType typeCls2 = typeIface != null || ifaces.Count > 0 + ? SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT) + : null; // Search the class first (except possibly object). if (typeCls1 == null || LookupInClass(typeCls1, ref typeCls2)) @@ -612,37 +601,37 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_swtFirst) { // Ambiguous lookup. - return GetErrorContext().Error(ErrorCode.ERR_AmbigMember, _swtFirst, _swtAmbig); + return ErrorHandling.Error(ErrorCode.ERR_AmbigMember, _swtFirst, _swtAmbig); } if (_swtInaccess) { return !_swtInaccess.Sym.isUserCallable() && ((_flags & MemLookFlags.UserCallable) != 0) - ? GetErrorContext().Error(ErrorCode.ERR_CantCallSpecialMethod, _swtInaccess) - : GetSemanticChecker().ReportAccessError(_swtInaccess, _symWhere, _typeQual); + ? ErrorHandling.Error(ErrorCode.ERR_CantCallSpecialMethod, _swtInaccess) + : CSemanticChecker.ReportAccessError(_swtInaccess, _symWhere, _typeQual); } if ((_flags & MemLookFlags.Ctor) != 0) { Debug.Assert(_typeSrc is AggregateType); return _arity > 0 - ? GetErrorContext().Error(ErrorCode.ERR_BadCtorArgCount, ((AggregateType)_typeSrc).OwningAggregate, _arity) - : GetErrorContext().Error(ErrorCode.ERR_NoConstructors, ((AggregateType)_typeSrc).OwningAggregate); + ? ErrorHandling.Error(ErrorCode.ERR_BadCtorArgCount, ((AggregateType)_typeSrc).OwningAggregate, _arity) + : ErrorHandling.Error(ErrorCode.ERR_NoConstructors, ((AggregateType)_typeSrc).OwningAggregate); } if ((_flags & MemLookFlags.Operator) != 0) { - return GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); + return ErrorHandling.Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); } if ((_flags & MemLookFlags.Indexer) != 0) { - return GetErrorContext().Error(ErrorCode.ERR_BadIndexLHS, _typeSrc); + return ErrorHandling.Error(ErrorCode.ERR_BadIndexLHS, _typeSrc); } if (_swtBad) { - return GetErrorContext().Error((_flags & MemLookFlags.MustBeInvocable) != 0 ? ErrorCode.ERR_NonInvocableMemberCalled : ErrorCode.ERR_CantCallSpecialMethod, _swtBad); + return ErrorHandling.Error((_flags & MemLookFlags.MustBeInvocable) != 0 ? ErrorCode.ERR_NonInvocableMemberCalled : ErrorCode.ERR_CantCallSpecialMethod, _swtBad); } if (_swtBogus) @@ -657,13 +646,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (_swtBadArity.Sym is MethodSymbol badMeth) { int cvar = badMeth.typeVars.Count; - return GetErrorContext().Error(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym), cvar); + return ErrorHandling.Error(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym), cvar); } - return GetErrorContext().Error(ErrorCode.ERR_TypeArgsNotAllowed, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym)); + return ErrorHandling.Error(ErrorCode.ERR_TypeArgsNotAllowed, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym)); } - return GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); + return ErrorHandling.Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookupResults.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookupResults.cs index 045a6cd..7c21f14 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookupResults.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MemberLookupResults.cs @@ -29,15 +29,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } public CMethodIterator GetMethodIterator( - CSemanticChecker pChecker, SymbolLoader pSymLoader, CType pQualifyingType, AggregateDeclaration pContext, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) - { - Debug.Assert(pSymLoader != null); - CMethodIterator iterator = new CMethodIterator(pChecker, pSymLoader, _pName, ContainingTypes, pQualifyingType, pContext, arity, flags, mask, nonTrailingNamedArguments); - return iterator; - } - - public partial class CMethodIterator - { - } + CType qualifyingType, AggregateSymbol context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) => + new CMethodIterator(_pName, ContainingTypes, qualifyingType, context, arity, flags, mask, nonTrailingNamedArguments); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodIterator.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodIterator.cs index 8ba78c3..be5d2a5 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodIterator.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodIterator.cs @@ -10,12 +10,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal partial class CMemberLookupResults { - public partial class CMethodIterator + public class CMethodIterator { - private readonly SymbolLoader _symbolLoader; - private readonly CSemanticChecker _semanticChecker; // Inputs. - private readonly AggregateDeclaration _context; + private readonly AggregateSymbol _context; private readonly TypeArray _containingTypes; private readonly CType _qualifyingType; private readonly Name _name; @@ -26,15 +24,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Internal state. private int _currentTypeIndex; - public CMethodIterator(CSemanticChecker checker, SymbolLoader symLoader, Name name, TypeArray containingTypes, CType qualifyingType, AggregateDeclaration context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) + public CMethodIterator(Name name, TypeArray containingTypes, CType qualifyingType, AggregateSymbol context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) { Debug.Assert(name != null); - Debug.Assert(symLoader != null); - Debug.Assert(checker != null); Debug.Assert(containingTypes != null); Debug.Assert(containingTypes.Count != 0); - _semanticChecker = checker; - _symbolLoader = symLoader; + _name = name; _containingTypes = containingTypes; _qualifyingType = qualifyingType; @@ -87,7 +82,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } // Check access. If Sym is not accessible, then let it through and mark it. - IsCurrentSymbolInaccessible = !_semanticChecker.CheckAccess(CurrentSymbol, CurrentType, _context, _qualifyingType); + IsCurrentSymbolInaccessible = !CSemanticChecker.CheckAccess(CurrentSymbol, CurrentType, _context, _qualifyingType); // Check bogus. If Sym is bogus, then let it through and mark it. IsCurrentSymbolBogus = CSemanticChecker.CheckBogus(CurrentSymbol); @@ -104,7 +99,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (args != null) { List paramNames = ExpressionBinder.GroupToArgsBinder - .FindMostDerivedMethod(_symbolLoader, CurrentSymbol, _qualifyingType) + .FindMostDerivedMethod(CurrentSymbol, _qualifyingType) .ParameterNames; List argExpressions = args.prgexpr; @@ -129,8 +124,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics for (;;) { CurrentSymbol = (CurrentSymbol == null - ? _symbolLoader.LookupAggMember(_name, CurrentType.OwningAggregate, _mask) - : SymbolLoader.LookupNextSym(CurrentSymbol, CurrentType.OwningAggregate, _mask)) as MethodOrPropertySymbol; + ? SymbolLoader.LookupAggMember(_name, CurrentType.OwningAggregate, _mask) + : CurrentSymbol.LookupNext(_mask)) as MethodOrPropertySymbol; // If we couldn't find a sym, we look up the type chain and get the next type. if (CurrentSymbol == null) diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs index 24c26c3..efb6593 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/MethodTypeInferrer.cs @@ -27,7 +27,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics DependsMask = 0x10, Indirect = 0x12 } - private readonly SymbolLoader _symbolLoader; + private readonly ExpressionBinder _binder; private readonly TypeArray _pMethodTypeParameters; private readonly TypeArray _pMethodFormalParameterTypes; @@ -81,7 +81,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public static bool Infer( ExpressionBinder binder, - SymbolLoader symbolLoader, MethodSymbol pMethod, TypeArray pMethodFormalParameterTypes, ArgInfos pMethodArguments, @@ -99,9 +98,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(pMethodFormalParameterTypes != null); Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.Count); - var inferrer = new MethodTypeInferrer(binder, symbolLoader, - pMethodFormalParameterTypes, pMethodArguments, - pMethod.typeVars); + var inferrer = new MethodTypeInferrer( + binder, pMethodFormalParameterTypes, pMethodArguments, pMethod.typeVars); bool success = inferrer.InferTypeArgs(); ppInferredTypeArguments = inferrer.GetResults(); @@ -118,12 +116,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // SPEC: with an empty set of bounds. private MethodTypeInferrer( - ExpressionBinder exprBinder, SymbolLoader symLoader, - TypeArray pMethodFormalParameterTypes, ArgInfos pMethodArguments, - TypeArray pMethodTypeParameters) + ExpressionBinder exprBinder, TypeArray pMethodFormalParameterTypes, ArgInfos pMethodArguments, TypeArray pMethodTypeParameters) { _binder = exprBinder; - _symbolLoader = symLoader; _pMethodFormalParameterTypes = pMethodFormalParameterTypes; _pMethodArguments = pMethodArguments; _pMethodTypeParameters = pMethodTypeParameters; @@ -142,7 +137,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// - private TypeArray GetResults() => GetGlobalSymbols().AllocParams(_pFixedResults); + private TypeArray GetResults() => TypeArray.Allocate(_pFixedResults); //////////////////////////////////////////////////////////////////////////////// @@ -1709,7 +1704,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // since we can never infer ref/out or pointer types here, we // are guaranteed a best accessible type. - _pFixedResults[iParam] = GetTypeManager().GetBestAccessibleType(_binder.GetSemanticChecker(), _binder.GetContext().ContextForMemberLookup, pBest); + _pFixedResults[iParam] = TypeManager.GetBestAccessibleType(_binder.Context.ContextForMemberLookup, pBest); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // END RUNTIME BINDER ONLY CHANGE // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -1717,32 +1712,5 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics UpdateDependenciesAfterFix(iParam); return true; } - - //////////////////////////////////////////////////////////////////////////////// - // - // Helper methods - // - - //////////////////////////////////////////////////////////////////////////////// - - - private SymbolLoader GetSymbolLoader() - { - return _symbolLoader; - } - - //////////////////////////////////////////////////////////////////////////////// - - private TypeManager GetTypeManager() - { - return GetSymbolLoader().GetTypeManager(); - } - - //////////////////////////////////////////////////////////////////////////////// - - private BSYMMGR GetGlobalSymbols() - { - return GetSymbolLoader().getBSymmgr(); - } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs index eaa58d3..425e910 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Nullable.cs @@ -3,25 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using Microsoft.CSharp.RuntimeBinder.Errors; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class CNullable + internal readonly partial struct ExpressionBinder { - private readonly SymbolLoader _pSymbolLoader; - private readonly ExprFactory _exprFactory; - private readonly ErrorHandling _pErrorContext; - - private SymbolLoader GetSymbolLoader() - { - return _pSymbolLoader; - } - private ExprFactory GetExprFactory() - { - return _exprFactory; - } - private static bool IsNullableConstructor(Expr expr, out ExprCall call) { Debug.Assert(expr != null); @@ -37,7 +23,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - public static Expr StripNullableConstructor(Expr pExpr) + private static Expr StripNullableConstructor(Expr pExpr) { while (IsNullableConstructor(pExpr, out ExprCall call)) { @@ -48,15 +34,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pExpr; } - // Value - public Expr BindValue(Expr exprSrc) + // Create an expr for exprSrc.Value where exprSrc.type is a NullableType. + private static Expr BindNubValue(Expr exprSrc) { Debug.Assert(exprSrc != null && exprSrc.Type is NullableType); // For new T?(x), the answer is x. if (IsNullableConstructor(exprSrc, out ExprCall call)) { - var args = call.OptionalArguments; + Expr args = call.OptionalArguments; Debug.Assert(args != null && !(args is ExprList)); return args; } @@ -64,59 +50,24 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics NullableType nubSrc = (NullableType)exprSrc.Type; CType typeBase = nubSrc.UnderlyingType; AggregateType ats = nubSrc.GetAts(); - PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; - if (prop == null) - { - prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); - Debug.Assert(prop != null); - GetSymbolLoader().getBSymmgr().propNubValue = prop; - } - + PropertySymbol prop = PredefinedMembers.GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); PropWithType pwt = new PropWithType(prop, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); - return GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, null); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(exprSrc, mpwi); + return ExprFactory.CreateProperty(typeBase, null, null, pMemGroup, pwt, null); } - public ExprCall BindNew(Expr pExprSrc) + // Create an expr for new T?(exprSrc) where T is exprSrc.type. + private static ExprCall BindNubNew(Expr exprSrc) { - Debug.Assert(pExprSrc != null); - - NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.Type); + Debug.Assert(exprSrc != null); + NullableType pNubSourceType = TypeManager.GetNullable(exprSrc.Type); AggregateType pSourceType = pNubSourceType.GetAts(); - MethodSymbol meth = GetSymbolLoader().getBSymmgr().methNubCtor; - if (meth == null) - { - meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR); - Debug.Assert(meth != null); - GetSymbolLoader().getBSymmgr().methNubCtor = meth; - } - - MethWithInst methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray()); - ExprMemberGroup memgroup = GetExprFactory().CreateMemGroup(null, methwithinst); - return GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst); - } - public CNullable(SymbolLoader symbolLoader, ErrorHandling errorContext, ExprFactory exprFactory) - { - _pSymbolLoader = symbolLoader; - _pErrorContext = errorContext; - _exprFactory = exprFactory; - } - } - - internal sealed partial class ExpressionBinder - { - // Create an expr for exprSrc.Value where exprSrc.type is a NullableType. - private Expr BindNubValue(Expr exprSrc) - { - return m_nullable.BindValue(exprSrc); - } - - // Create an expr for new T?(exprSrc) where T is exprSrc.type. - private ExprCall BindNubNew(Expr exprSrc) - { - return m_nullable.BindNew(exprSrc); + MethodSymbol meth = PredefinedMembers.GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR); + MethWithInst methwithinst = new MethWithInst(meth, pSourceType, TypeArray.Empty); + ExprMemberGroup memgroup = ExprFactory.CreateMemGroup(null, methwithinst); + return ExprFactory.CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, exprSrc, memgroup, methwithinst); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs index 1e6b5ae..13f8b2f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs @@ -10,7 +10,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { /* These are the predefined binary operator signatures @@ -80,16 +80,60 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Method pointers must be in the order of the corresponding enums. We check this when the full signature is set. // When the binding method is looked up in these arrays we ASSERT // if the array is out of bounds of the corresponding array. - - private readonly BinOpSig[] g_binopSignatures; + private static readonly BinOpSig[] s_binopSignatures = + { + new BinOpSig (PredefinedType.PT_INT, PredefinedType.PT_INT, BinOpMask.Integer, 8, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), + new BinOpSig (PredefinedType.PT_UINT, PredefinedType.PT_UINT, BinOpMask.Integer, 7, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), + new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_LONG, BinOpMask.Integer, 6, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), + new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_ULONG, BinOpMask.Integer, 5, BindIntBinOp, OpSigFlags.Value, BinOpFuncKind.IntBinOp ), + /* ERROR */ + new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_LONG, BinOpMask.Integer, 4, null, OpSigFlags.Value, BinOpFuncKind.None ), + /* ERROR */ + new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_ULONG, BinOpMask.Integer, 3, null, OpSigFlags.Value, BinOpFuncKind.None ), + new BinOpSig (PredefinedType.PT_FLOAT, PredefinedType.PT_FLOAT, BinOpMask.Real, 1, BindRealBinOp, OpSigFlags.Value, BinOpFuncKind.RealBinOp ), + new BinOpSig (PredefinedType.PT_DOUBLE, PredefinedType.PT_DOUBLE, BinOpMask.Real, 0, BindRealBinOp, OpSigFlags.Value, BinOpFuncKind.RealBinOp ), + new BinOpSig (PredefinedType.PT_DECIMAL, PredefinedType.PT_DECIMAL, BinOpMask.Real, 0, BindDecBinOp, OpSigFlags.Value, BinOpFuncKind.DecBinOp ), + new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_STRING, BinOpMask.Equal, 0, BindStrCmpOp, OpSigFlags.Reference, BinOpFuncKind.StrCmpOp ), + new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_STRING, BinOpMask.Add, 2, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), + new BinOpSig (PredefinedType.PT_STRING, PredefinedType.PT_OBJECT, BinOpMask.Add, 1, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), + new BinOpSig (PredefinedType.PT_OBJECT, PredefinedType.PT_STRING, BinOpMask.Add, 0, BindStrBinOp, OpSigFlags.Reference, BinOpFuncKind.StrBinOp ), + new BinOpSig (PredefinedType.PT_INT, PredefinedType.PT_INT, BinOpMask.Shift, 3, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), + new BinOpSig (PredefinedType.PT_UINT, PredefinedType.PT_INT, BinOpMask.Shift, 2, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), + new BinOpSig (PredefinedType.PT_LONG, PredefinedType.PT_INT, BinOpMask.Shift, 1, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), + new BinOpSig (PredefinedType.PT_ULONG, PredefinedType.PT_INT, BinOpMask.Shift, 0, BindShiftOp, OpSigFlags.Value, BinOpFuncKind.ShiftOp ), + new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.BoolNorm, 0, BindBoolBinOp, OpSigFlags.Value, BinOpFuncKind.BoolBinOp ), + // Make boolean logical operators liftable so that they don't give funny short circuiting semantics. + // This is for DDBugs 677075. + new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.Logical, 0, BindBoolBinOp, OpSigFlags.BoolBit, BinOpFuncKind.BoolBinOp ), + new BinOpSig (PredefinedType.PT_BOOL, PredefinedType.PT_BOOL, BinOpMask.Bitwise, 0, BindLiftedBoolBitwiseOp, OpSigFlags.BoolBit, BinOpFuncKind.BoolBitwiseOp ), + }; // We want unary minus to bind to "operator -(ulong)" and then we // produce an error (since there is no pfn). We can't let - bind to a floating point type, // since they lose precision. See the language spec. // Increment and decrement operators are special. + private static readonly UnaOpSig[] s_rguos = + { + new UnaOpSig( PredefinedType.PT_INT, UnaOpMask.Signed, 7, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), + new UnaOpSig( PredefinedType.PT_UINT, UnaOpMask.Unsigned, 6, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), + new UnaOpSig( PredefinedType.PT_LONG, UnaOpMask.Signed, 5, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), + new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.Unsigned, 4, BindIntUnaOp, UnaOpFuncKind.IntUnaOp ), + /* ERROR */ + new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.Minus, 3, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_FLOAT, UnaOpMask.Real, 1, BindRealUnaOp, UnaOpFuncKind.RealUnaOp ), + new UnaOpSig( PredefinedType.PT_DOUBLE, UnaOpMask.Real, 0, BindRealUnaOp, UnaOpFuncKind.RealUnaOp ), + new UnaOpSig( PredefinedType.PT_DECIMAL, UnaOpMask.Real, 0, BindDecUnaOp, UnaOpFuncKind.DecUnaOp ), + new UnaOpSig( PredefinedType.PT_BOOL, UnaOpMask.Bool, 0, BindBoolUnaOp, UnaOpFuncKind.BoolUnaOp ), + new UnaOpSig( PredefinedType.PT_INT, UnaOpMask.IncDec, 6, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_UINT, UnaOpMask.IncDec, 5, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_LONG, UnaOpMask.IncDec, 4, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_ULONG, UnaOpMask.IncDec, 3, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_FLOAT, UnaOpMask.IncDec, 1, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_DOUBLE, UnaOpMask.IncDec, 0, null, UnaOpFuncKind.None ), + new UnaOpSig( PredefinedType.PT_DECIMAL, UnaOpMask.IncDec, 0, null, UnaOpFuncKind.None ), + }; - private readonly UnaOpSig[] g_rguos; private ExprBinOp BindUserDefinedBinOp(ExpressionKind ek, BinOpArgInfo info) { @@ -122,7 +166,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return null; } - return GetExprFactory().CreateUserDefinedBinop(ek, expr.Type, info.arg1, info.arg2, expr, pmpwi); + return ExprFactory.CreateUserDefinedBinop(ek, expr.Type, info.arg1, info.arg2, expr, pmpwi); } // Adds special signatures to the candidate list. If we find an exact match @@ -147,9 +191,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(rgbofs != null); int ibosMinLift = 0; - for (int ibos = 0; ibos < g_binopSignatures.Length; ibos++) + for (int ibos = 0; ibos < s_binopSignatures.Length; ibos++) { - BinOpSig bos = g_binopSignatures[ibos]; + BinOpSig bos = s_binopSignatures[ibos]; if ((bos.mask & info.mask) == 0) { continue; @@ -191,7 +235,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(typeSig1.IsValueType); - typeSig1 = GetSymbolLoader().GetTypeManager().GetNullable(typeSig1); + typeSig1 = TypeManager.GetNullable(typeSig1); if (!canConvert(constant, typeSig1)) { continue; @@ -218,7 +262,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(typeSig1.IsValueType); - typeSig1 = GetSymbolLoader().GetTypeManager().GetNullable(typeSig1); + typeSig1 = TypeManager.GetNullable(typeSig1); if (!canConvert(info.arg1, typeSig1)) { continue; @@ -275,7 +319,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(typeSig2.IsValueType); - typeSig2 = GetSymbolLoader().GetTypeManager().GetNullable(typeSig2); + typeSig2 = TypeManager.GetNullable(typeSig2); if (!canConvert(constant, typeSig2)) { continue; @@ -303,7 +347,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(typeSig2.IsValueType); - typeSig2 = GetSymbolLoader().GetTypeManager().GetNullable(typeSig2); + typeSig2 = TypeManager.GetNullable(typeSig2); if (!canConvert(info.arg2, typeSig2)) { continue; @@ -401,7 +445,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return bestSignature; } - private ExprBinOp bindNullEqualityComparison(ExpressionKind ek, BinOpArgInfo info) + private static ExprBinOp BindNullEqualityComparison(ExpressionKind ek, BinOpArgInfo info) { Expr arg1 = info.arg1; Expr arg2 = info.arg2; @@ -411,13 +455,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ExprBinOp exprRes = null; if (info.type1 is NullableType && info.type2 is NullType) { - arg2 = GetExprFactory().CreateZeroInit(info.type1); - exprRes = GetExprFactory().CreateBinop(ek, typeBool, arg1, arg2); + arg2 = ExprFactory.CreateZeroInit(info.type1); + exprRes = ExprFactory.CreateBinop(ek, typeBool, arg1, arg2); } if (info.type1 is NullType && info.type2 is NullableType) { - arg1 = GetExprFactory().CreateZeroInit(info.type2); - exprRes = GetExprFactory().CreateBinop(ek, typeBool, arg1, arg2); + arg1 = ExprFactory.CreateZeroInit(info.type2); + exprRes = ExprFactory.CreateBinop(ek, typeBool, arg1, arg2); } if (exprRes != null) { @@ -481,7 +525,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // If we got no matches then it's possible that we're in the case // x == null, where x is nullable. - return bindNullEqualityComparison(ek, info); + return BindNullEqualityComparison(ek, info); } else { @@ -494,7 +538,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Ambiguous. - throw AmbiguousOperatorError(ek, arg1, arg2); + throw AmbiguousOperatorError(arg1, arg2); } } @@ -523,11 +567,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics expr1 = mustConvert(expr1, bofs.Type1()); expr2 = mustConvert(expr2, bofs.Type2()); } + if (bofs.fnkind == BinOpFuncKind.BoolBitwiseOp) { - return BindBoolBitwiseOp(ek, flags, expr1, expr2, bofs); + return BindBoolBitwiseOp(ek, flags, expr1, expr2); } - return bofs.pfn(ek, flags, expr1, expr2); + + return bofs.pfn(this, ek, flags, expr1, expr2); } Debug.Assert(bofs.fnkind != BinOpFuncKind.BoolBitwiseOp); if (IsEnumArithmeticBinOp(ek, info)) @@ -567,7 +613,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Only compute the method if theres no nulls. If there are, we'll special case it // later, since operations with a null operand are null. - nonLiftedResult = bofs.pfn(ek, flags, nonLiftedArg1, nonLiftedArg2); + nonLiftedResult = bofs.pfn(this, ek, flags, nonLiftedArg1, nonLiftedArg2); } // Check if we have a comparison. If so, set the result type to bool. @@ -584,11 +630,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (!(resultType is NullableType)) { - resultType = GetSymbolLoader().GetTypeManager().GetNullable(resultType); + resultType = TypeManager.GetNullable(resultType); } } - ExprBinOp exprRes = GetExprFactory().CreateBinop(ek, resultType, pArgument1, pArgument2); + ExprBinOp exprRes = ExprFactory.CreateBinop(ek, resultType, pArgument1, pArgument2); mustCast(nonLiftedResult, resultType, 0); exprRes.IsLifted = true; exprRes.Flags |= flags; @@ -684,7 +730,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics else { pgrflt = LiftFlags.None; - typeDst = GetSymbolLoader().GetTypeManager().GetNullable(typeDst); + typeDst = TypeManager.GetNullable(typeDst); if (!canConvert(info.arg1, typeDst)) return false; pgrflt = LiftFlags.Convert1; @@ -694,7 +740,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (info.type2 is NullableType) { pgrflt = pgrflt | LiftFlags.Lift2; - ptypeSig2 = GetSymbolLoader().GetTypeManager().GetNullable(info.typeRaw2); + ptypeSig2 = TypeManager.GetNullable(info.typeRaw2); } else ptypeSig2 = info.typeRaw2; @@ -718,7 +764,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics else { pgrflt = LiftFlags.None; - typeDst = GetSymbolLoader().GetTypeManager().GetNullable(typeDst); + typeDst = TypeManager.GetNullable(typeDst); if (!canConvert(info.arg2, typeDst)) return false; pgrflt = LiftFlags.Convert2; @@ -728,7 +774,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (info.type1 is NullableType) { pgrflt = pgrflt | LiftFlags.Lift1; - ptypeSig1 = GetSymbolLoader().GetTypeManager().GetNullable(info.typeRaw1); + ptypeSig1 = TypeManager.GetNullable(info.typeRaw1); } else ptypeSig1 = info.typeRaw1; @@ -741,7 +787,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Record the appropriate binary operator full signature from the given BinOpArgInfo. This assumes that any NullableType valued args should be lifted. */ - private void RecordBinOpSigFromArgs(List prgbofs, BinOpArgInfo info) + private static void RecordBinOpSigFromArgs(List prgbofs, BinOpArgInfo info) { LiftFlags grflt = LiftFlags.None; CType typeSig1; @@ -751,19 +797,23 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Debug.Assert(info.type1 is NullableType); grflt = grflt | LiftFlags.Lift1; - typeSig1 = GetSymbolLoader().GetTypeManager().GetNullable(info.typeRaw1); + typeSig1 = TypeManager.GetNullable(info.typeRaw1); } else + { typeSig1 = info.typeRaw1; + } if (info.type2 != info.typeRaw2) { Debug.Assert(info.type2 is NullableType); grflt = grflt | LiftFlags.Lift2; - typeSig2 = GetSymbolLoader().GetTypeManager().GetNullable(info.typeRaw2); + typeSig2 = TypeManager.GetNullable(info.typeRaw2); } else + { typeSig2 = info.typeRaw2; + } prgbofs.Add(new BinOpFullSig(typeSig1, typeSig2, BindEnumBinOp, OpSigFlags.Value, grflt, BinOpFuncKind.EnumBinOp)); } @@ -793,6 +843,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { return false; } + RecordBinOpSigFromArgs(prgbofs, info); return true; } @@ -828,7 +879,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - private bool IsEnumArithmeticBinOp(ExpressionKind ek, BinOpArgInfo info) + private static bool IsEnumArithmeticBinOp(ExpressionKind ek, BinOpArgInfo info) { switch (ek) { @@ -920,7 +971,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; if (type1.IsInterfaceType || type1.IsPredefType(PredefinedType.PT_STRING) - || GetSymbolLoader().HasBaseConversion(type1, typeDel)) + || SymbolLoader.HasBaseConversion(type1, typeDel)) type1 = typeObj; else if (type1 is ArrayType) type1 = GetPredefindType(PredefinedType.PT_ARRAY); @@ -928,7 +979,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; if (type2.IsInterfaceType || type2.IsPredefType(PredefinedType.PT_STRING) - || GetSymbolLoader().HasBaseConversion(type2, typeDel)) + || SymbolLoader.HasBaseConversion(type2, typeDel)) type2 = typeObj; else if (type2 is ArrayType) type2 = GetPredefindType(PredefinedType.PT_ARRAY); @@ -942,9 +993,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics type2.IsClassType && !type2.IsPredefType(PredefinedType.PT_STRING) && !type2.IsPredefType(PredefinedType.PT_DELEGATE)); - if (GetSymbolLoader().HasBaseConversion(type2, type1)) + if (SymbolLoader.HasBaseConversion(type2, type1)) typeCls = type1; - else if (GetSymbolLoader().HasBaseConversion(type1, type2)) + else if (SymbolLoader.HasBaseConversion(type1, type2)) typeCls = type2; } @@ -1133,7 +1184,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return mustCast( BindStandardUnaryOperator( - op, mustCast(pArgument, GetTypes().GetNullable(GetPredefindType(ptOp)))), nub); + op, mustCast(pArgument, TypeManager.GetNullable(GetPredefindType(ptOp)))), nub); } } @@ -1195,7 +1246,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (nBestSignature < 0) { // Ambiguous. - throw AmbiguousOperatorError(ek, pArgument, null); + throw AmbiguousOperatorError(pArgument, null); } // Verify that our answer works. @@ -1207,7 +1258,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } if (WhichUofsIsBetter(pSignatures[nBestSignature], pSignatures[iuofs], type) >= 0) { - throw AmbiguousOperatorError(ek, pArgument, null); + throw AmbiguousOperatorError(pArgument, null); } } } @@ -1250,7 +1301,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { arg = mustCast(pArgument, uofs.GetType(), CONVERTTYPE.NOUDC); } - return uofs.pfn(ek, flags, arg); + + return uofs.pfn(this, ek, flags, arg); } ///////////////////////////////////////////////////////////////////////////////// @@ -1307,7 +1359,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(!(pArgumentType is PointerType)); // Check for user defined inc/dec - ExprMultiGet exprGet = GetExprFactory().CreateMultiGet(0, pArgumentType, null); + ExprMultiGet exprGet = ExprFactory.CreateMultiGet(0, pArgumentType, null); Expr exprVal = bindUDUnop((ExpressionKind)(exprKind - ExpressionKind.Add + ExpressionKind.Inc), exprGet); if (exprVal != null) @@ -1318,7 +1370,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } Debug.Assert(pArgument != null); - ExprMulti exprMulti = GetExprFactory().CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, pArgumentType, pArgument, exprVal); + ExprMulti exprMulti = ExprFactory.CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, pArgumentType, pArgument, exprVal); exprGet.OptionalMulti = exprMulti; // Check whether Lvalue can be assigned. @@ -1361,15 +1413,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics PredefinedType pt = pArgumentType.IsPredefined ? pArgumentType.PredefinedType : PredefinedType.PT_COUNT; PredefinedType ptRaw = pRawType.IsPredefined ? pRawType.PredefinedType : PredefinedType.PT_COUNT; - for (int index = 0; index < g_rguos.Length; index++) + for (int index = 0; index < s_rguos.Length; index++) { - UnaOpSig uos = g_rguos[index]; + UnaOpSig uos = s_rguos[index]; if ((uos.grfuom & unaryOpMask) == 0) { continue; } - ConvKind cv = GetConvKind(pt, g_rguos[index].pt); + ConvKind cv = GetConvKind(pt, s_rguos[index].pt); CType typeSig = null; switch (cv) @@ -1395,7 +1447,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { continue; } - typeSig = GetSymbolLoader().GetTypeManager().GetNullable(typeSig); + typeSig = TypeManager.GetNullable(typeSig); if (!canConvert(pArgument, typeSig)) { continue; @@ -1411,7 +1463,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { continue; } - typeSig = GetSymbolLoader().GetTypeManager().GetNullable(typeSig); + typeSig = TypeManager.GetNullable(typeSig); if (!canConvert(pArgument, typeSig)) { continue; @@ -1482,8 +1534,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics LiftArgument(arg, uofs.GetType(), uofs.Convert(), out Expr pArgument, out Expr nonLiftedArg); // Now call the function with the non lifted arguments to report errors. - Expr nonLiftedResult = uofs.pfn(ek, flags, nonLiftedArg); - ExprUnaryOp exprRes = GetExprFactory().CreateUnaryOp(ek, type, pArgument); + Expr nonLiftedResult = uofs.pfn(this, ek, flags, nonLiftedArg); + ExprUnaryOp exprRes = ExprFactory.CreateUnaryOp(ek, type, pArgument); mustCast(nonLiftedResult, type, 0); exprRes.Flags |= flags; @@ -1524,40 +1576,40 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics /* Handles standard binary integer based operators. */ - private ExprOperator BindIntBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprOperator BindIntBinOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(arg1.Type.IsPredefined && arg2.Type.IsPredefined && arg1.Type.PredefinedType == arg2.Type.PredefinedType); - return BindIntOp(ek, flags, arg1, arg2, arg1.Type.PredefinedType); + return binder.BindIntOp(ek, flags, arg1, arg2, arg1.Type.PredefinedType); } /* Handles standard unary integer based operators. */ - private ExprOperator BindIntUnaOp(ExpressionKind ek, EXPRFLAG flags, Expr arg) + private static ExprOperator BindIntUnaOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr arg) { Debug.Assert(arg.Type.IsPredefined); - return BindIntOp(ek, flags, arg, null, arg.Type.PredefinedType); + return binder.BindIntOp(ek, flags, arg, null, arg.Type.PredefinedType); } /* Handles standard binary floating point (float, double) based operators. */ - private ExprOperator BindRealBinOp(ExpressionKind ek, EXPRFLAG _, Expr arg1, Expr arg2) + private static ExprOperator BindRealBinOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG _, Expr arg1, Expr arg2) { Debug.Assert(arg1.Type.IsPredefined && arg2.Type.IsPredefined && arg1.Type.PredefinedType == arg2.Type.PredefinedType); - return bindFloatOp(ek, arg1, arg2); + return BindFloatOp(ek, arg1, arg2); } /* Handles standard unary floating point (float, double) based operators. */ - private ExprOperator BindRealUnaOp(ExpressionKind ek, EXPRFLAG _, Expr arg) + private static ExprOperator BindRealUnaOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG _, Expr arg) { Debug.Assert(arg.Type.IsPredefined); - return bindFloatOp(ek, arg, null); + return BindFloatOp(ek, arg, null); } @@ -1652,7 +1704,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics typeOne = typeOne.UnderlyingEnumType; } - ExprBinOp pExprResult = GetExprFactory().CreateBinop(ek, typeTmp, exprVal, GetExprFactory().CreateConstant(typeOne, cv)); + ExprBinOp pExprResult = ExprFactory.CreateBinop(ek, typeTmp, exprVal, ExprFactory.CreateConstant(typeOne, cv)); pExprResult.Flags |= flags; return typeTmp != type ? mustCast(pExprResult, type, CONVERTTYPE.NOUDC) : pExprResult; } @@ -1663,7 +1715,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(!uofs.isLifted()); Debug.Assert(arg != null); - ExprMultiGet exprGet = GetExprFactory().CreateMultiGet(EXPRFLAG.EXF_ASSGOP, arg.Type, null); + ExprMultiGet exprGet = ExprFactory.CreateMultiGet(EXPRFLAG.EXF_ASSGOP, arg.Type, null); Expr exprVal = exprGet; CType type = uofs.GetType(); Debug.Assert(!(type is NullableType)); @@ -1678,7 +1730,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics exprVal = BindIncOpCore(ek, flags, exprVal, type); Expr op = mustCast(exprVal, arg.Type, CONVERTTYPE.NOUDC); - ExprMulti exprMulti = GetExprFactory().CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, arg.Type, arg, op); + ExprMulti exprMulti = ExprFactory.CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, arg.Type, arg, op); exprGet.OptionalMulti = exprMulti; return exprMulti; } @@ -1691,7 +1743,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics NullableType type = uofs.GetType() as NullableType; Debug.Assert(arg != null); - ExprMultiGet exprGet = GetExprFactory().CreateMultiGet(EXPRFLAG.EXF_ASSGOP, arg.Type, null); + ExprMultiGet exprGet = ExprFactory.CreateMultiGet(EXPRFLAG.EXF_ASSGOP, arg.Type, null); Expr exprVal = exprGet; Expr nonLiftedArg = exprVal; @@ -1701,11 +1753,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics nonLiftedArg = mustCast(nonLiftedArg, type.UnderlyingType); Expr nonLiftedResult = BindIncOpCore(ek, flags, nonLiftedArg, type.UnderlyingType); exprVal = mustCast(exprVal, type); - ExprUnaryOp exprRes = GetExprFactory().CreateUnaryOp((ek == ExpressionKind.Add) ? ExpressionKind.Inc : ExpressionKind.Dec, arg.Type/* type */, exprVal); + ExprUnaryOp exprRes = ExprFactory.CreateUnaryOp((ek == ExpressionKind.Add) ? ExpressionKind.Inc : ExpressionKind.Dec, arg.Type/* type */, exprVal); mustCast(mustCast(nonLiftedResult, type), arg.Type); exprRes.Flags |= flags; - ExprMulti exprMulti = GetExprFactory().CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, arg.Type, arg, exprRes); + ExprMulti exprMulti = ExprFactory.CreateMulti(EXPRFLAG.EXF_ASSGOP | flags, arg.Type, arg, exprRes); exprGet.OptionalMulti = exprMulti; return exprMulti; } @@ -1715,7 +1767,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics This function is called twice by the EE for every binary operator it evaluates Here is how it works. */ - private ExprBinOp BindDecBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprBinOp BindDecBinOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(arg1.Type.IsPredefType(PredefinedType.PT_DECIMAL) && arg2.Type.IsPredefType(PredefinedType.PT_DECIMAL)); @@ -1747,14 +1799,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics break; } - return GetExprFactory().CreateBinop(ek, typeRet, arg1, arg2); + return ExprFactory.CreateBinop(ek, typeRet, arg1, arg2); } /* Handles standard unary decimal based operators. */ - private ExprUnaryOp BindDecUnaOp(ExpressionKind ek, EXPRFLAG flags, Expr arg) + private static ExprUnaryOp BindDecUnaOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg) { Debug.Assert(arg.Type.IsPredefType(PredefinedType.PT_DECIMAL)); Debug.Assert(ek == ExpressionKind.Negate || ek == ExpressionKind.UnaryPlus); @@ -1767,18 +1819,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics PREDEFMETH predefMeth = PREDEFMETH.PM_DECIMAL_OPUNARYMINUS; return CreateUnaryOpForPredefMethodCall(ExpressionKind.DecimalNegate, predefMeth, typeDec, arg); } - return GetExprFactory().CreateUnaryOp(ExpressionKind.UnaryPlus, typeDec, arg); + return ExprFactory.CreateUnaryOp(ExpressionKind.UnaryPlus, typeDec, arg); } /* Handles string concatenation. */ - private Expr BindStrBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static Expr BindStrBinOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(ek == ExpressionKind.Add); Debug.Assert(arg1.Type.IsPredefType(PredefinedType.PT_STRING) || arg2.Type.IsPredefType(PredefinedType.PT_STRING)); - return bindStringConcat(arg1, arg2); + return BindStringConcat(arg1, arg2); } @@ -1786,7 +1838,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Bind a shift operator: <<, >>. These can have integer or long first operands, and second operand must be int. */ - private ExprBinOp BindShiftOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprBinOp BindShiftOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(ek == ExpressionKind.LeftShirt || ek == ExpressionKind.RightShift); Debug.Assert(arg1.Type.IsPredefined); @@ -1795,24 +1847,24 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics PredefinedType ptOp = arg1.Type.PredefinedType; Debug.Assert(ptOp == PredefinedType.PT_INT || ptOp == PredefinedType.PT_UINT || ptOp == PredefinedType.PT_LONG || ptOp == PredefinedType.PT_ULONG); - return GetExprFactory().CreateBinop(ek, arg1.Type, arg1, arg2); + return ExprFactory.CreateBinop(ek, arg1.Type, arg1, arg2); } /* Bind a bool binary operator: ==, !=, &&, ||, , |, ^. If both operands are constant, the result will be a constant also. */ - private ExprBinOp BindBoolBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprBinOp BindBoolBinOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(arg1 != null); Debug.Assert(arg2 != null); Debug.Assert(arg1.Type.IsPredefType(PredefinedType.PT_BOOL) || arg1.Type is NullableType argNubType1 && argNubType1.UnderlyingType.IsPredefType(PredefinedType.PT_BOOL)); Debug.Assert(arg2.Type.IsPredefType(PredefinedType.PT_BOOL) || arg2.Type is NullableType argNubType2 && argNubType2.UnderlyingType.IsPredefType(PredefinedType.PT_BOOL)); - return GetExprFactory().CreateBinop(ek, GetPredefindType(PredefinedType.PT_BOOL), arg1, arg2); + return ExprFactory.CreateBinop(ek, GetPredefindType(PredefinedType.PT_BOOL), arg1, arg2); } - private ExprOperator BindBoolBitwiseOp(ExpressionKind ek, EXPRFLAG flags, Expr expr1, Expr expr2, BinOpFullSig bofs) + private ExprOperator BindBoolBitwiseOp(ExpressionKind ek, EXPRFLAG flags, Expr expr1, Expr expr2) { Debug.Assert(ek == ExpressionKind.BitwiseAnd || ek == ExpressionKind.BitwiseOr); Debug.Assert(expr1.Type.IsPredefType(PredefinedType.PT_BOOL) || expr1.Type is NullableType expNubType1 && expNubType1.UnderlyingType.IsPredefType(PredefinedType.PT_BOOL)); @@ -1821,20 +1873,20 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (expr1.Type is NullableType || expr2.Type is NullableType) { CType typeBool = GetPredefindType(PredefinedType.PT_BOOL); - CType typeRes = GetSymbolLoader().GetTypeManager().GetNullable(typeBool); + CType typeRes = TypeManager.GetNullable(typeBool); // Get the non-lifted result. - Expr nonLiftedArg1 = CNullable.StripNullableConstructor(expr1); - Expr nonLiftedArg2 = CNullable.StripNullableConstructor(expr2); + Expr nonLiftedArg1 = StripNullableConstructor(expr1); + Expr nonLiftedArg2 = StripNullableConstructor(expr2); Expr nonLiftedResult = null; if (!(nonLiftedArg1.Type is NullableType) && !(nonLiftedArg2.Type is NullableType)) { - nonLiftedResult = BindBoolBinOp(ek, flags, nonLiftedArg1, nonLiftedArg2); + nonLiftedResult = BindBoolBinOp(this, ek, flags, nonLiftedArg1, nonLiftedArg2); } // Make the binop and set that its lifted. - ExprBinOp exprRes = GetExprFactory().CreateBinop(ek, typeRes, expr1, expr2); + ExprBinOp exprRes = ExprFactory.CreateBinop(ek, typeRes, expr1, expr2); if (nonLiftedResult != null) { // Bitwise operators can have null non-lifted results if we have a nub sym somewhere. @@ -1845,19 +1897,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert((exprRes.Flags & EXPRFLAG.EXF_LVALUE) == 0); return exprRes; } - return BindBoolBinOp(ek, flags, expr1, expr2); - } - private Expr BindLiftedBoolBitwiseOp(ExpressionKind ek, EXPRFLAG flags, Expr expr1, Expr expr2) - { - return null; + return BindBoolBinOp(this, ek, flags, expr1, expr2); } + private static Expr BindLiftedBoolBitwiseOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr expr1, Expr expr2) => null; /* Handles boolean unary operator (!). */ - private Expr BindBoolUnaOp(ExpressionKind ek, EXPRFLAG flags, Expr arg) + private static Expr BindBoolUnaOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg) { Debug.Assert(arg.Type.IsPredefType(PredefinedType.PT_BOOL)); Debug.Assert(ek == ExpressionKind.LogicalNot); @@ -1871,16 +1920,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr argConst = arg.GetConst(); if (argConst == null) - return GetExprFactory().CreateUnaryOp(ExpressionKind.LogicalNot, typeBool, arg); + return ExprFactory.CreateUnaryOp(ExpressionKind.LogicalNot, typeBool, arg); - return GetExprFactory().CreateConstant(typeBool, ConstVal.Get(((ExprConstant)argConst).Val.Int32Val == 0)); + return ExprFactory.CreateConstant(typeBool, ConstVal.Get(((ExprConstant)argConst).Val.Int32Val == 0)); } /* Handles string equality. */ - private ExprBinOp BindStrCmpOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprBinOp BindStrCmpOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(ek == ExpressionKind.Eq || ek == ExpressionKind.NotEq); Debug.Assert(arg1.Type.IsPredefType(PredefinedType.PT_STRING) && arg2.Type.IsPredefType(PredefinedType.PT_STRING)); @@ -1897,22 +1946,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics /* Handles reference equality operators. Type variables come through here. */ - private ExprBinOp BindRefCmpOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static ExprBinOp BindRefCmpOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(ek == ExpressionKind.Eq || ek == ExpressionKind.NotEq); // Must box type variables for the verifier. - arg1 = mustConvert(arg1, GetPredefindType(PredefinedType.PT_OBJECT), CONVERTTYPE.NOUDC); - arg2 = mustConvert(arg2, GetPredefindType(PredefinedType.PT_OBJECT), CONVERTTYPE.NOUDC); + arg1 = binder.mustConvert(arg1, GetPredefindType(PredefinedType.PT_OBJECT), CONVERTTYPE.NOUDC); + arg2 = binder.mustConvert(arg2, GetPredefindType(PredefinedType.PT_OBJECT), CONVERTTYPE.NOUDC); - return GetExprFactory().CreateBinop(ek, GetPredefindType(PredefinedType.PT_BOOL), arg1, arg2); + return ExprFactory.CreateBinop(ek, GetPredefindType(PredefinedType.PT_BOOL), arg1, arg2); } /* Handles delegate binary operators. */ - private Expr BindDelBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static Expr BindDelBinOp(ExpressionBinder _, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { Debug.Assert(ek == ExpressionKind.Add || ek == ExpressionKind.Subtract || ek == ExpressionKind.Eq || ek == ExpressionKind.NotEq); Debug.Assert(arg1.Type == arg2.Type && (arg1.Type.IsDelegateType || arg1.Type.IsPredefType(PredefinedType.PT_DELEGATE))); @@ -1952,7 +2001,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics /* Handles enum binary operators. */ - private Expr BindEnumBinOp(ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) + private static Expr BindEnumBinOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr arg1, Expr arg2) { AggregateType typeDst = GetEnumBinOpType(ek, arg1.Type, arg2.Type, out AggregateType typeEnum); @@ -1977,15 +2026,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } CType typeOp = GetPredefindType(ptOp); - arg1 = mustCast(arg1, typeOp, CONVERTTYPE.NOUDC); - arg2 = mustCast(arg2, typeOp, CONVERTTYPE.NOUDC); + arg1 = binder.mustCast(arg1, typeOp, CONVERTTYPE.NOUDC); + arg2 = binder.mustCast(arg2, typeOp, CONVERTTYPE.NOUDC); - Expr exprRes = BindIntOp(ek, flags, arg1, arg2, ptOp); + Expr exprRes = binder.BindIntOp(ek, flags, arg1, arg2, ptOp); if (exprRes.Type != typeDst) { Debug.Assert(!typeDst.IsPredefType(PredefinedType.PT_BOOL)); - exprRes = mustCast(exprRes, typeDst, CONVERTTYPE.NOUDC); + exprRes = binder.mustCast(exprRes, typeDst, CONVERTTYPE.NOUDC); } return exprRes; @@ -2005,7 +2054,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics nonNullableType2 = nonNullableType1.UnderlyingEnumType; } - NullableType typeDst = GetTypes().GetNullable(GetEnumBinOpType(ek, nonNullableType1, nonNullableType2, out AggregateType typeEnum)); + NullableType typeDst = TypeManager.GetNullable(GetEnumBinOpType(ek, nonNullableType1, nonNullableType2, out AggregateType typeEnum)); Debug.Assert(typeEnum != null); PredefinedType ptOp; @@ -2027,11 +2076,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics break; } - NullableType typeOp = GetTypes().GetNullable(GetPredefindType(ptOp)); + NullableType typeOp = TypeManager.GetNullable(GetPredefindType(ptOp)); arg1 = mustCast(arg1, typeOp, CONVERTTYPE.NOUDC); arg2 = mustCast(arg2, typeOp, CONVERTTYPE.NOUDC); - ExprBinOp exprRes = GetExprFactory().CreateBinop(ek, typeOp, arg1, arg2); + ExprBinOp exprRes = ExprFactory.CreateBinop(ek, typeOp, arg1, arg2); exprRes.IsLifted = true; exprRes.Flags |= flags; Debug.Assert((exprRes.Flags & EXPRFLAG.EXF_LVALUE) == 0); @@ -2048,7 +2097,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics /* Handles enum unary operator (~). */ - private Expr BindEnumUnaOp(ExpressionKind ek, EXPRFLAG flags, Expr arg) + private static Expr BindEnumUnaOp(ExpressionBinder binder, ExpressionKind ek, EXPRFLAG flags, Expr arg) { Debug.Assert(ek == ExpressionKind.BitwiseNot); Debug.Assert((ExprCast)arg != null); @@ -2075,10 +2124,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } CType typeOp = GetPredefindType(ptOp); - arg = mustCast(arg, typeOp, CONVERTTYPE.NOUDC); + arg = binder.mustCast(arg, typeOp, CONVERTTYPE.NOUDC); - Expr exprRes = BindIntOp(ek, flags, arg, null, ptOp); - return mustCastInUncheckedContext(exprRes, typeEnum, CONVERTTYPE.NOUDC); + Expr exprRes = binder.BindIntOp(ek, flags, arg, null, ptOp); + return binder.MustCastInUncheckedContext(exprRes, typeEnum, CONVERTTYPE.NOUDC); } /* @@ -2176,7 +2225,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType typeDest = kind.IsRelational() ? GetPredefindType(PredefinedType.PT_BOOL) : typeOp; - ExprOperator exprRes = GetExprFactory().CreateOperator(kind, typeDest, op1, op2); + ExprOperator exprRes = ExprFactory.CreateOperator(kind, typeDest, op1, op2); exprRes.Flags |= flags; Debug.Assert((exprRes.Flags & EXPRFLAG.EXF_LVALUE) == 0); return exprRes; @@ -2229,7 +2278,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics op = mustConvertCore(op, GetPredefindType(PredefinedType.PT_LONG), CONVERTTYPE.NOUDC); } - ExprOperator exprRes = GetExprFactory().CreateNeg(flags, op); + ExprOperator exprRes = ExprFactory.CreateNeg(flags, op); Debug.Assert(0 == (exprRes.Flags & EXPRFLAG.EXF_LVALUE)); return exprRes; } @@ -2239,7 +2288,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics will be a constant also. op2 can be null for a unary operator. The operands are assumed to be already converted to the correct type. */ - private ExprOperator bindFloatOp(ExpressionKind kind, Expr op1, Expr op2) + private static ExprOperator BindFloatOp(ExpressionKind kind, Expr op1, Expr op2) { //Debug.Assert(kind.isRelational() || kind.isArithmetic()); Debug.Assert(op2 == null || op1.Type == op2.Type); @@ -2248,13 +2297,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Allocate the result expression. CType typeDest = kind.IsRelational() ? GetPredefindType(PredefinedType.PT_BOOL) : op1.Type; - ExprOperator exprRes = GetExprFactory().CreateOperator(kind, typeDest, op1, op2); + ExprOperator exprRes = ExprFactory.CreateOperator(kind, typeDest, op1, op2); exprRes.Flags &= ~EXPRFLAG.EXF_CHECKOVERFLOW; return exprRes; } - private ExprConcat bindStringConcat(Expr op1, Expr op2) + private static ExprConcat BindStringConcat(Expr op1, Expr op2) { // If the concatenation consists solely of two constants then we must // realize the concatenation into a single constant node at this time. @@ -2274,13 +2323,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(op1 != null); Debug.Assert(op2 != null); - return GetExprFactory().CreateConcat(op1, op2); + return ExprFactory.CreateConcat(op1, op2); } /* Report an ambiguous operator types error. */ - private RuntimeBinderException AmbiguousOperatorError(ExpressionKind ek, Expr op1, Expr op2) + private static RuntimeBinderException AmbiguousOperatorError(Expr op1, Expr op2) { Debug.Assert(op1 != null); @@ -2290,8 +2339,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Bad arg types - report error to user. return op2 != null - ? GetErrorContext().Error(ErrorCode.ERR_AmbigBinaryOps, strOp, op1.Type, op2.Type) - : GetErrorContext().Error(ErrorCode.ERR_AmbigUnaryOp, strOp, op1.Type); + ? ErrorHandling.Error(ErrorCode.ERR_AmbigBinaryOps, strOp, op1.Type, op2.Type) + : ErrorHandling.Error(ErrorCode.ERR_AmbigUnaryOp, strOp, op1.Type); } private Expr BindUserBoolOp(ExpressionKind kind, ExprCall pCall) @@ -2304,10 +2353,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType typeRet = pCall.Type; Debug.Assert(pCall.MethWithInst.Meth().Params.Count == 2); - if (!GetTypes().SubstEqualTypes(typeRet, pCall.MethWithInst.Meth().Params[0], typeRet) || - !GetTypes().SubstEqualTypes(typeRet, pCall.MethWithInst.Meth().Params[1], typeRet)) + if (!TypeManager.SubstEqualTypes(typeRet, pCall.MethWithInst.Meth().Params[0], typeRet) || + !TypeManager.SubstEqualTypes(typeRet, pCall.MethWithInst.Meth().Params[1], typeRet)) { - throw GetErrorContext().Error(ErrorCode.ERR_BadBoolOp, pCall.MethWithInst); + throw ErrorHandling.Error(ErrorCode.ERR_BadBoolOp, pCall.MethWithInst); } ExprList list = (ExprList)pCall.OptionalArguments; @@ -2318,23 +2367,23 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics list.OptionalElement = pExprWrap; // Reflection load the true and false methods. - SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_True, null, pExprWrap.Type.AssociatedSystemType); - SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_False, null, pExprWrap.Type.AssociatedSystemType); + SymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_True, null, pExprWrap.Type.AssociatedSystemType); + SymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_False, null, pExprWrap.Type.AssociatedSystemType); Expr pCallT = bindUDUnop(ExpressionKind.True, pExprWrap); Expr pCallF = bindUDUnop(ExpressionKind.False, pExprWrap); if (pCallT == null || pCallF == null) { - throw GetErrorContext().Error(ErrorCode.ERR_MustHaveOpTF, typeRet); + throw ErrorHandling.Error(ErrorCode.ERR_MustHaveOpTF, typeRet); } pCallT = mustConvert(pCallT, GetPredefindType(PredefinedType.PT_BOOL)); pCallF = mustConvert(pCallF, GetPredefindType(PredefinedType.PT_BOOL)); - return GetExprFactory().CreateUserLogOp(typeRet, kind == ExpressionKind.LogicalAnd ? pCallF : pCallT, pCall); + return ExprFactory.CreateUserLogOp(typeRet, kind == ExpressionKind.LogicalAnd ? pCallF : pCallT, pCall); } - private AggregateType GetUserDefinedBinopArgumentType(CType type) + private static AggregateType GetUserDefinedBinopArgumentType(CType type) { if (type is NullableType nt) { @@ -2349,7 +2398,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return null; } - private int GetUserDefinedBinopArgumentTypes(CType type1, CType type2, AggregateType[] rgats) + private static int GetUserDefinedBinopArgumentTypes(CType type1, CType type2, AggregateType[] rgats) { int cats = 0; rgats[0] = GetUserDefinedBinopArgumentType(type1); @@ -2370,7 +2419,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return cats; } - private bool UserDefinedBinaryOperatorCanBeLifted(ExpressionKind ek, MethodSymbol method, AggregateType ats, + private static bool UserDefinedBinaryOperatorCanBeLifted(ExpressionKind ek, MethodSymbol method, AggregateType ats, TypeArray Params) { if (!Params[0].IsNonNullableValueType || !Params[1].IsNonNullableValueType) @@ -2378,7 +2427,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - CType typeRet = GetTypes().SubstType(method.RetType, ats); + CType typeRet = TypeManager.SubstType(method.RetType, ats); if (!typeRet.IsNonNullableValueType) { return false; @@ -2421,11 +2470,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } Debug.Assert(method.typeVars.Count == 0); - TypeArray paramsCur = GetTypes().SubstTypeArray(method.Params, ats); + TypeArray paramsCur = TypeManager.SubstTypeArray(method.Params, ats); if (canConvert(arg1, paramsCur[0]) && canConvert(arg2, paramsCur[1])) { candidateList.Add(new CandidateFunctionMember( - new MethPropWithInst(method, ats, BSYMMGR.EmptyTypeArray()), + new MethPropWithInst(method, ats, TypeArray.Empty), paramsCur, 0, // No lifted arguments false)); @@ -2436,15 +2485,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } CType[] rgtype = new CType[2]; - rgtype[0] = GetTypes().GetNullable(paramsCur[0]); - rgtype[1] = GetTypes().GetNullable(paramsCur[1]); + rgtype[0] = TypeManager.GetNullable(paramsCur[0]); + rgtype[1] = TypeManager.GetNullable(paramsCur[1]); if (!canConvert(arg1, rgtype[0]) || !canConvert(arg2, rgtype[1])) { return false; } candidateList.Add(new CandidateFunctionMember( - new MethPropWithInst(method, ats, BSYMMGR.EmptyTypeArray()), - GetGlobalSymbols().AllocParams(2, rgtype), + new MethPropWithInst(method, ats, TypeArray.Empty), + TypeArray.Allocate(rgtype), 2, // two lifted arguments false)); return true; @@ -2454,12 +2503,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics List candidateList, ExpressionKind ek, AggregateType type, Expr arg1, Expr arg2, bool fDontLift) { - Name name = ekName(ek); + Name name = ExpressionKindName(ek); Debug.Assert(name != null); bool foundSome = false; - for (MethodSymbol methCur = GetSymbolLoader().LookupAggMember(name, type.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; + for (MethodSymbol methCur = SymbolLoader.LookupAggMember(name, type.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; methCur != null; - methCur = SymbolLoader.LookupNextSym(methCur, type.OwningAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol) + methCur = methCur.LookupNext(symbmask_t.MASK_MethodSymbol) as MethodSymbol) { if (UserDefinedBinaryOperatorIsApplicable(candidateList, ek, methCur, type, arg1, arg2, fDontLift)) { @@ -2514,7 +2563,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return null; } - ExprList args = GetExprFactory().CreateList(arg1, arg2); + ExprList args = ExprFactory.CreateList(arg1, arg2); ArgInfos info = new ArgInfos(); info.carg = 2; FillInArgInfoFromArgList(info, args); @@ -2525,7 +2574,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (pmethBest == null) { // No winner, so its an ambiguous call... - throw GetErrorContext().Error(ErrorCode.ERR_AmbigCall, pmethAmbig1.mpwi, pmethAmbig2.mpwi); + throw ErrorHandling.Error(ErrorCode.ERR_AmbigCall, pmethAmbig1.mpwi, pmethAmbig2.mpwi); } ppmpwi = pmethBest.mpwi; @@ -2537,7 +2586,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return BindLiftedUDBinop(ek, arg1, arg2, pmethBest.@params, pmethBest.mpwi); } - CType typeRetRaw = GetTypes().SubstType(pmethBest.mpwi.Meth().RetType, pmethBest.mpwi.GetType()); + CType typeRetRaw = TypeManager.SubstType(pmethBest.mpwi.Meth().RetType, pmethBest.mpwi.GetType()); return BindUDBinopCall(arg1, arg2, pmethBest.@params, typeRetRaw, pmethBest.mpwi); } @@ -2546,15 +2595,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { arg1 = mustConvert(arg1, Params[0]); arg2 = mustConvert(arg2, Params[1]); - ExprList args = GetExprFactory().CreateList(arg1, arg2); + ExprList args = ExprFactory.CreateList(arg1, arg2); - checkUnsafe(arg1.Type); // added to the binder so we don't bind to pointer ops - checkUnsafe(arg2.Type); // added to the binder so we don't bind to pointer ops - checkUnsafe(typeRet); // added to the binder so we don't bind to pointer ops + CheckUnsafe(arg1.Type); // added to the binder so we don't bind to pointer ops + CheckUnsafe(arg2.Type); // added to the binder so we don't bind to pointer ops + CheckUnsafe(typeRet); // added to the binder so we don't bind to pointer ops - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi); - ExprCall call = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, null); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mpwi); + ExprCall call = ExprFactory.CreateCall(0, typeRet, args, pMemGroup, null); call.MethWithInst = new MethWithInst(mpwi); verifyMethodArgs(call, mpwi.GetType()); return call; @@ -2565,7 +2614,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr exprVal1 = arg1; Expr exprVal2 = arg2; CType typeRet; - CType typeRetRaw = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType()); + CType typeRetRaw = TypeManager.SubstType(mpwi.Meth().RetType, mpwi.GetType()); // This is a lifted user defined operator. We know that both arguments // go to the nullable formal parameter types, and that at least one @@ -2577,7 +2626,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // argument to the nullable formal parameter type first, before we then // do the cast for the non-nullable call. - TypeArray paramsRaw = GetTypes().SubstTypeArray(mpwi.Meth().Params, mpwi.GetType()); + TypeArray paramsRaw = TypeManager.SubstTypeArray(mpwi.Meth().Params, mpwi.GetType()); Debug.Assert(Params != paramsRaw); Debug.Assert(paramsRaw[0] == Params[0].BaseOrParameterOrElementType); Debug.Assert(paramsRaw[1] == Params[1].BaseOrParameterOrElementType); @@ -2595,7 +2644,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics switch (ek) { default: - typeRet = GetTypes().GetNullable(typeRetRaw); + typeRet = TypeManager.GetNullable(typeRetRaw); break; case ExpressionKind.Eq: case ExpressionKind.NotEq: @@ -2620,9 +2669,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ExprCall nonLiftedResult = BindUDBinopCall(nonLiftedArg1, nonLiftedArg2, paramsRaw, typeRetRaw, mpwi); - ExprList args = GetExprFactory().CreateList(exprVal1, exprVal2); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi); - ExprCall call = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, null); + ExprList args = ExprFactory.CreateList(exprVal1, exprVal2); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mpwi); + ExprCall call = ExprFactory.CreateCall(0, typeRet, args, pMemGroup, null); call.MethWithInst = new MethWithInst(mpwi); switch (ek) @@ -2644,7 +2693,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return call; } - private AggregateType GetEnumBinOpType(ExpressionKind ek, CType argType1, CType argType2, out AggregateType ppEnumType) + private static AggregateType GetEnumBinOpType(ExpressionKind ek, CType argType1, CType argType2, out AggregateType ppEnumType) { Debug.Assert(argType1.IsEnumType || argType2.IsEnumType); @@ -2685,29 +2734,29 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return typeDst; } - private ExprBinOp CreateBinopForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType RetType, Expr arg1, Expr arg2) + private static ExprBinOp CreateBinopForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType RetType, Expr arg1, Expr arg2) { - MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMeth); + MethodSymbol methSym = PredefinedMembers.GetMethod(predefMeth); Debug.Assert(methSym != null); - ExprBinOp binop = GetExprFactory().CreateBinop(ek, RetType, arg1, arg2); + ExprBinOp binop = ExprFactory.CreateBinop(ek, RetType, arg1, arg2); // Set the predefined method to call. AggregateSymbol agg = methSym.getClass(); - AggregateType callingType = GetTypes().GetAggregate(agg, BSYMMGR.EmptyTypeArray()); + AggregateType callingType = TypeManager.GetAggregate(agg, TypeArray.Empty); binop.PredefinedMethodToCall = new MethWithInst(methSym, callingType, null); binop.UserDefinedCallMethod = binop.PredefinedMethodToCall; return binop; } - private ExprUnaryOp CreateUnaryOpForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType pRetType, Expr pArg) + private static ExprUnaryOp CreateUnaryOpForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType pRetType, Expr pArg) { - MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMeth); + MethodSymbol methSym = PredefinedMembers.GetMethod(predefMeth); Debug.Assert(methSym != null); - ExprUnaryOp pUnaryOp = GetExprFactory().CreateUnaryOp(ek, pRetType, pArg); + ExprUnaryOp pUnaryOp = ExprFactory.CreateUnaryOp(ek, pRetType, pArg); // Set the predefined method to call. AggregateSymbol pAgg = methSym.getClass(); - AggregateType pCallingType = GetTypes().GetAggregate(pAgg, BSYMMGR.EmptyTypeArray()); + AggregateType pCallingType = TypeManager.GetAggregate(pAgg, TypeArray.Empty); pUnaryOp.PredefinedMethodToCall = new MethWithInst(methSym, pCallingType, null); pUnaryOp.UserDefinedCallMethod = pUnaryOp.PredefinedMethodToCall; return pUnaryOp; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/PredefinedMembers.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/PredefinedMembers.cs index 5f136a9..39a4c22 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/PredefinedMembers.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/PredefinedMembers.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using Microsoft.CSharp.RuntimeBinder.Errors; using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics @@ -190,40 +189,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics this.name = name; this.getter = getter; } - }; + } // Loads and caches predefined members. // Also finds constructors on delegate types. - internal sealed class PredefinedMembers + internal static class PredefinedMembers { - private readonly SymbolLoader _loader; - internal SymbolTable RuntimeBinderSymbolTable; - private readonly MethodSymbol[] _methods = new MethodSymbol[(int)PREDEFMETH.PM_COUNT]; - private readonly PropertySymbol[] _properties = new PropertySymbol[(int)PREDEFPROP.PP_COUNT]; - - private Name GetMethName(PREDEFMETH method) - { - return GetPredefName(GetMethPredefName(method)); - } - - private AggregateSymbol GetMethParent(PREDEFMETH method) - { - return GetPredefAgg(GetMethPredefType(method)); - } + private static readonly MethodSymbol[] _methods = new MethodSymbol[(int)PREDEFMETH.PM_COUNT]; + private static readonly PropertySymbol[] _properties = new PropertySymbol[(int)PREDEFPROP.PP_COUNT]; - private PropertySymbol LoadProperty(PREDEFPROP property) + private static PropertySymbol LoadProperty(PREDEFPROP property) { - return LoadProperty( - property, - GetPropName(property), - GetPropGetter(property)); + PredefinedPropertyInfo info = GetPropInfo(property); + return LoadProperty(property, NameManager.GetPredefinedName(info.name), info.getter); } - private Name GetPropName(PREDEFPROP property) - { - return GetPredefName(GetPropPredefName(property)); - } - private PropertySymbol LoadProperty( + private static PropertySymbol LoadProperty( PREDEFPROP predefProp, Name propertyName, PREDEFMETH propertyGetter) @@ -231,7 +212,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(propertyName != null); Debug.Assert(propertyGetter >= 0 && propertyGetter < PREDEFMETH.PM_COUNT); - RuntimeBinderSymbolTable.AddPredefinedPropertyToSymbolTable( + SymbolTable.AddPredefinedPropertyToSymbolTable( GetPredefAgg(GetPropPredefType(predefProp)), propertyName); MethodSymbol getter = GetMethod(propertyGetter); @@ -241,32 +222,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return property; } - private SymbolLoader GetSymbolLoader() - { - Debug.Assert(_loader != null); + private static AggregateSymbol GetPredefAgg(PredefinedType pt) => SymbolLoader.GetPredefAgg(pt); - return _loader; - } - - private TypeManager GetTypeManager() - { - return GetSymbolLoader().GetTypeManager(); - } - private BSYMMGR getBSymmgr() - { - return GetSymbolLoader().getBSymmgr(); - } - - private Name GetPredefName(PredefinedName pn) - { - return NameManager.GetPredefinedName(pn); - } - private AggregateSymbol GetPredefAgg(PredefinedType pt) - { - return GetSymbolLoader().GetPredefAgg(pt); - } - - private CType LoadTypeFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars) + private static CType LoadTypeFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars) { Debug.Assert(signature != null); @@ -276,11 +234,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics switch (current) { case MethodSignatureEnum.SIG_SZ_ARRAY: - return GetTypeManager() - .GetArray(LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars), 1, true); + return TypeManager.GetArray(LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars), 1, true); case MethodSignatureEnum.SIG_METH_TYVAR: - return GetTypeManager().GetStdMethTypeVar(signature[indexIntoSignatures++]); + return TypeManager.GetStdMethTypeVar(signature[indexIntoSignatures++]); case MethodSignatureEnum.SIG_CLASS_TYVAR: return classTyVars[signature[indexIntoSignatures++]]; @@ -294,7 +251,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics int typeCount = agg.GetTypeVars().Count; if (typeCount == 0) { - return GetTypeManager().GetAggregate(agg, BSYMMGR.EmptyTypeArray()); + return TypeManager.GetAggregate(agg, TypeArray.Empty); } CType[] typeArgs = new CType[typeCount]; @@ -303,11 +260,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics typeArgs[iTypeArg] = LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars); } - return GetTypeManager().GetAggregate(agg, getBSymmgr().AllocParams(typeArgs)); + return TypeManager.GetAggregate(agg, TypeArray.Allocate(typeArgs)); } } - private TypeArray LoadTypeArrayFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars) + private static TypeArray LoadTypeArrayFromSignature(int[] signature, ref int indexIntoSignatures, TypeArray classTyVars) { Debug.Assert(signature != null); @@ -322,18 +279,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ptypes[i] = LoadTypeFromSignature(signature, ref indexIntoSignatures, classTyVars); } - return getBSymmgr().AllocParams(count, ptypes); + return TypeArray.Allocate(ptypes); } - public PredefinedMembers(SymbolLoader loader) - { - _loader = loader; - Debug.Assert(_loader != null); - - _methods = new MethodSymbol[(int)PREDEFMETH.PM_COUNT]; - _properties = new PropertySymbol[(int)PREDEFPROP.PP_COUNT]; - #if DEBUG + static PredefinedMembers() + { // validate the tables for (int i = 0; i < (int)PREDEFMETH.PM_COUNT; i++) { @@ -343,22 +294,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Debug.Assert((int)GetPropInfo((PREDEFPROP)i).property == i); } -#endif } +#endif - public PropertySymbol GetProperty(PREDEFPROP property) + public static PropertySymbol GetProperty(PREDEFPROP property) { Debug.Assert(property >= 0 && property < PREDEFPROP.PP_COUNT); return _properties[(int)property] ?? (_properties[(int)property] = LoadProperty(property)); } - public MethodSymbol GetMethod(PREDEFMETH method) + public static MethodSymbol GetMethod(PREDEFMETH method) { Debug.Assert(method >= 0 && method < PREDEFMETH.PM_COUNT); return _methods[(int)method] ?? (_methods[(int)method] = LoadMethod(method)); } - private MethodSymbol LoadMethod( + private static MethodSymbol LoadMethod( AggregateSymbol type, int[] signature, int cMethodTyVars, @@ -385,17 +336,17 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (ret == null) { - RuntimeBinderSymbolTable.AddPredefinedMethodToSymbolTable(type, methodName); + SymbolTable.AddPredefinedMethodToSymbolTable(type, methodName); ret = LookupMethodWhileLoading(type, cMethodTyVars, methodName, methodAccess, isStatic, isVirtual, returnType, argumentTypes); } return ret; } - private MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes) + private static MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes) { - for (Symbol sym = GetSymbolLoader().LookupAggMember(methodName, type, symbmask_t.MASK_ALL); + for (Symbol sym = SymbolLoader.LookupAggMember(methodName, type, symbmask_t.MASK_ALL); sym != null; - sym = SymbolLoader.LookupNextSym(sym, type, symbmask_t.MASK_ALL)) + sym = sym.LookupNext(symbmask_t.MASK_ALL)) { if (sym is MethodSymbol methsym) { @@ -403,8 +354,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics methsym.isStatic == isStatic && methsym.isVirtual == isVirtual && methsym.typeVars.Count == cMethodTyVars && - GetTypeManager().SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, true) && - GetTypeManager().SubstEqualTypeArrays(methsym.Params, argumentTypes, null, methsym.typeVars)) + TypeManager.SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, true) && + TypeManager.SubstEqualTypeArrays(methsym.Params, argumentTypes, null, methsym.typeVars)) { return methsym; } @@ -413,21 +364,17 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return null; } - private MethodSymbol LoadMethod(PREDEFMETH method) + private static MethodSymbol LoadMethod(PREDEFMETH method) { + PredefinedMethodInfo info = GetMethInfo(method); return LoadMethod( - GetMethParent(method), - GetMethSignature(method), - GetMethTyVars(method), - GetMethName(method), - GetMethAccess(method), - IsMethStatic(method), - IsMethVirtual(method)); - } - - private static PredefinedName GetPropPredefName(PREDEFPROP property) - { - return GetPropInfo(property).name; + GetPredefAgg(info.type), + info.signature, + info.cTypeVars, + NameManager.GetPredefinedName(info.name), + info.access, + info.callingConvention == MethodCallingConventionEnum.Static, + info.callingConvention == MethodCallingConventionEnum.Virtual); } private static PREDEFMETH GetPropGetter(PREDEFPROP property) @@ -467,41 +414,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return s_predefinedMethods[(int)method]; } - private static PredefinedName GetMethPredefName(PREDEFMETH method) - { - return GetMethInfo(method).name; - } - - private static PredefinedType GetMethPredefType(PREDEFMETH method) - { - return GetMethInfo(method).type; - } - - private static bool IsMethStatic(PREDEFMETH method) - { - return GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Static; - } - - private static bool IsMethVirtual(PREDEFMETH method) - { - return GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Virtual; - } - - private static ACCESS GetMethAccess(PREDEFMETH method) - { - return GetMethInfo(method).access; - } - - private static int GetMethTyVars(PREDEFMETH method) - { - return GetMethInfo(method).cTypeVars; - } - - private static int[] GetMethSignature(PREDEFMETH method) - { - return GetMethInfo(method).signature; - } - // the list of predefined method definitions. // This list must be in the same order as the PREDEFMETH enum. private static readonly PredefinedMethodInfo[] s_predefinedMethods = new PredefinedMethodInfo[(int)PREDEFMETH.PM_COUNT] { diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/SemanticChecker.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/SemanticChecker.cs index d34a776..1d30a83 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/SemanticChecker.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/SemanticChecker.cs @@ -18,18 +18,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // Semantic check methods on SymbolLoader // - internal sealed class CSemanticChecker + internal static class CSemanticChecker { // Generate an error if CType is static. - public void CheckForStaticClass(CType type) + public static void CheckForStaticClass(CType type) { if (type.IsStaticClass) { - throw ErrorContext.Error(ErrorCode.ERR_ConvertToStaticClass, type); + throw ErrorHandling.Error(ErrorCode.ERR_ConvertToStaticClass, type); } } - public ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) + public static ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { Debug.Assert(symCheck != null); Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.OwningAggregate); @@ -60,8 +60,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } // Check the accessibility of the return CType. - CType CType = symCheck.getType(); - if (CType == null) + CType type = symCheck.getType(); + if (type == null) { return ACCESSERROR.ACCESSERROR_NOERROR; } @@ -72,12 +72,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Substitute on the CType. if (atsCheck.TypeArgsAll.Count > 0) { - CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck); + type = TypeManager.SubstType(type, atsCheck); } - return CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS; + return CheckTypeAccess(type, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS; } - public bool CheckTypeAccess(CType type, Symbol symWhere) + + public static bool CheckTypeAccess(CType type, Symbol symWhere) { Debug.Assert(type != null); @@ -110,30 +111,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - // Generates an error for static classes - public SymbolLoader SymbolLoader { get; } = new SymbolLoader(); - - ///////////////////////////////////////////////////////////////////////////////// - // SymbolLoader forwarders (begin) - // - - public ErrorHandling ErrorContext => SymbolLoader.ErrorContext; - - public TypeManager GetTypeManager() { return SymbolLoader.GetTypeManager(); } - public BSYMMGR getBSymmgr() { return SymbolLoader.getBSymmgr(); } - public SymFactory GetGlobalSymbolFactory() { return SymbolLoader.GetGlobalSymbolFactory(); } - - //protected CompilerPhase GetCompPhase() { return SymbolLoader.CompPhase(); } - //protected void SetCompPhase(CompilerPhase compPhase) { SymbolLoader.compPhase = compPhase; } - public PredefinedTypes getPredefTypes() { return SymbolLoader.GetPredefindTypes(); } - // - // SymbolLoader forwarders (end) - ///////////////////////////////////////////////////////////////////////////////// - - // - // Utility methods - // - private ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) + private static ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { Debug.Assert(symCheck != null); Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.OwningAggregate); @@ -199,11 +177,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics aggWhere = aggSym; break; } - if (symT is AggregateDeclaration aggDec) - { - aggWhere = aggDec.Agg(); - break; - } } if (aggWhere == null) @@ -242,7 +215,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (typeThru != null && !symCheck.isStatic) { - atsThru = SymbolLoader.GetAggTypeSym(typeThru); + atsThru = typeThru.GetAts(); } // Look for aggCheck among the base classes of aggWhere and outer aggs. @@ -272,25 +245,20 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return found ? ACCESSERROR.ACCESSERROR_NOACCESSTHRU : ACCESSERROR.ACCESSERROR_NOACCESS; } - public static bool CheckBogus(Symbol sym) - { - return (sym as PropertySymbol)?.Bogus ?? false; - } + public static bool CheckBogus(Symbol sym) => (sym as PropertySymbol)?.Bogus ?? false; - public RuntimeBinderException ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual) + public static RuntimeBinderException ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual) { Debug.Assert(!CheckAccess(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) || !CheckTypeAccess(swtBad.GetType(), symWhere)); return CheckAccess2(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) == ACCESSERROR.ACCESSERROR_NOACCESSTHRU - ? ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere) - : ErrorContext.Error(ErrorCode.ERR_BadAccess, swtBad); + ? ErrorHandling.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere) + : ErrorHandling.Error(ErrorCode.ERR_BadAccess, swtBad); } - public bool CheckAccess(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) - { - return CheckAccess2(symCheck, atsCheck, symWhere, typeThru) == ACCESSERROR.ACCESSERROR_NOERROR; - } + public static bool CheckAccess(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) => + CheckAccess2(symCheck, atsCheck, symWhere, typeThru) == ACCESSERROR.ACCESSERROR_NOERROR; } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/AggregateSymbol.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/AggregateSymbol.cs index 864b2e9..8c6a189 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/AggregateSymbol.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/AggregateSymbol.cs @@ -32,8 +32,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics private TypeArray _typeVarsThis; // Type variables for this generic class, as declarations. private TypeArray _typeVarsAll; // The type variables for this generic class and all containing classes. - private TypeManager _pTypeManager; // This is so AGGTYPESYMs can instantiate their baseClass and ifacesAll members on demand. - // First UD conversion operator. This chain is for this type only (not base types). // The hasConversion flag indicates whether this or any base types have UD conversions. private MethodSymbol _pConvFirst; @@ -89,7 +87,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics AggregateType pOuterType = isNested() ? GetOuterAgg().getThisType() : null; - _atsInst = _pTypeManager.GetAggregate(this, pOuterType, GetTypeVars()); + _atsInst = TypeManager.GetAggregate(this, pOuterType, GetTypeVars()); } //Debug.Assert(GetTypeVars().Size == atsInst.GenericArguments.Count); @@ -223,16 +221,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// - public bool HasConversion(SymbolLoader pLoader) + public bool HasConversion() { - pLoader.RuntimeBinderSymbolTable.AddConversionsForType(AssociatedSystemType); + SymbolTable.AddConversionsForType(AssociatedSystemType); if (!_hasConversion.HasValue) { // ok, we tried defining all the conversions, and we didn't get anything // for this type. However, we will still think this type has conversions // if it's base type has conversions. - _hasConversion = GetBaseAgg() != null && GetBaseAgg().HasConversion(pLoader); + _hasConversion = GetBaseAgg() != null && GetBaseAgg().HasConversion(); } return _hasConversion.Value; @@ -291,11 +289,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } else { - outerTypeVars = BSYMMGR.EmptyTypeArray(); + outerTypeVars = TypeArray.Empty; } _typeVarsThis = typeVars; - _typeVarsAll = _pTypeManager.ConcatenateTypeArrays(outerTypeVars, typeVars); + _typeVarsAll = TypeArray.Concat(outerTypeVars, typeVars); } } @@ -344,16 +342,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics _ifacesAll = ifacesAll; } - public TypeManager GetTypeManager() - { - return _pTypeManager; - } - - public void SetTypeManager(TypeManager typeManager) - { - _pTypeManager = typeManager; - } - public MethodSymbol GetFirstUDConversion() { return _pConvFirst; @@ -364,9 +352,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics _pConvFirst = conv; } - public bool InternalsVisibleTo(Assembly assembly) - { - return _pTypeManager.InternalsVisibleTo(AssociatedAssembly, assembly); - } + public bool InternalsVisibleTo(Assembly assembly) => TypeManager.InternalsVisibleTo(AssociatedAssembly, assembly); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/FieldSymbol.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/FieldSymbol.cs index 30cd73a..996a1cc 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/FieldSymbol.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/FieldSymbol.cs @@ -37,10 +37,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public AggregateSymbol getClass() => parent as AggregateSymbol; - public EventSymbol getEvent(SymbolLoader symbolLoader) + public EventSymbol getEvent() { Debug.Assert(isEvent); - return symbolLoader.LookupAggMember(name, getClass(), symbmask_t.MASK_EventSymbol) as EventSymbol; + return SymbolLoader.LookupAggMember(name, getClass(), symbmask_t.MASK_EventSymbol) as EventSymbol; } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/NamespaceOrAggregateSymbol.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/NamespaceOrAggregateSymbol.cs index 2f9a029..d1d235f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/NamespaceOrAggregateSymbol.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/NamespaceOrAggregateSymbol.cs @@ -16,46 +16,5 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal abstract class NamespaceOrAggregateSymbol : ParentSymbol { - private AggregateDeclaration _declFirst; - private AggregateDeclaration _declLast; - - // ---------------------------------------------------------------------------- - // NamespaceOrAggregateSymbol - // ---------------------------------------------------------------------------- - - // Compare to ParentSymbol::AddToChildList - public void AddDecl(AggregateDeclaration decl) - { - Debug.Assert(decl != null); - Debug.Assert(this is AggregateSymbol); - Debug.Assert(decl is AggregateDeclaration); - - // If parent is set it should be set to us! - Debug.Assert(decl.bag == null || decl.bag == this); - // There shouldn't be a declNext. - Debug.Assert(decl.declNext == null); - - if (_declLast == null) - { - Debug.Assert(_declFirst == null); - _declFirst = _declLast = decl; - } - else - { - _declLast.declNext = decl; - _declLast = decl; - -#if DEBUG - // Validate our chain. - AggregateDeclaration pdecl; - for (pdecl = _declFirst; pdecl?.declNext != null; pdecl = pdecl.declNext) - { } - Debug.Assert(pdecl == null || (pdecl == _declLast && pdecl.declNext == null)); -#endif - } - - decl.declNext = null; - decl.bag = this; - } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactory.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactory.cs index e684b73..a59b513 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactory.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactory.cs @@ -7,16 +7,9 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class SymFactory + internal static class SymFactory { - private readonly SYMTBL _symbolTable; - - public SymFactory(SYMTBL symtable) - { - _symbolTable = symtable; - } - - private Symbol NewBasicSymbol( + private static Symbol NewBasicSymbol( SYMKIND kind, Name name, ParentSymbol parent) @@ -32,10 +25,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics sym = new AggregateSymbol(); sym.name = name; break; - case SYMKIND.SK_AggregateDeclaration: - sym = new AggregateDeclaration(); - sym.name = name; - break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; @@ -78,32 +67,29 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Set the parent element of the child symbol. parent.AddToChildList(sym); - _symbolTable.InsertChild(parent, sym); + SymbolStore.InsertChild(parent, sym); } - return (sym); + return sym; } // Namespace - public NamespaceSymbol CreateNamespace(Name name, NamespaceSymbol parent) + public static NamespaceSymbol CreateNamespace(Name name, NamespaceSymbol parent) { NamespaceSymbol sym = (NamespaceSymbol)NewBasicSymbol(SYMKIND.SK_NamespaceSymbol, name, parent); sym.SetAccess(ACCESS.ACC_PUBLIC); - return (sym); + return sym; } ///////////////////////////////////////////////////////////////////////////////// - public AggregateSymbol CreateAggregate(Name name, NamespaceOrAggregateSymbol parent, TypeManager typeManager) + public static AggregateSymbol CreateAggregate(Name name, NamespaceOrAggregateSymbol parent) { - if (name == null || parent == null || typeManager == null) - { - throw Error.InternalCompilerError(); - } + Debug.Assert(name != null); + Debug.Assert(parent != null); AggregateSymbol sym = (AggregateSymbol)NewBasicSymbol(SYMKIND.SK_AggregateSymbol, name, parent); sym.name = name; - sym.SetTypeManager(typeManager); sym.SetSealed(false); sym.SetAccess(ACCESS.ACC_UNKNOWN); sym.SetIfaces(null); @@ -113,33 +99,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return sym; } - public AggregateDeclaration CreateAggregateDecl(AggregateSymbol agg, AggregateDeclaration declOuter) - { - Debug.Assert(agg != null); - //Debug.Assert(declOuter == null || declOuter.Bag() == agg.Parent); - - // DECLSYMs are not parented like named symbols. - AggregateDeclaration sym = NewBasicSymbol(SYMKIND.SK_AggregateDeclaration, agg.name, null) as AggregateDeclaration; - - declOuter?.AddToChildList(sym); - agg.AddDecl(sym); - - Debug.Assert(sym != null); - return (sym); - } - // Members of aggs - public FieldSymbol CreateMemberVar(Name name, AggregateSymbol parent) + public static FieldSymbol CreateMemberVar(Name name, AggregateSymbol parent) { Debug.Assert(name != null); FieldSymbol sym = NewBasicSymbol(SYMKIND.SK_FieldSymbol, name, parent) as FieldSymbol; Debug.Assert(sym != null); - return (sym); + return sym; } - public LocalVariableSymbol CreateLocalVar(Name name, Scope parent, CType type) + public static LocalVariableSymbol CreateLocalVar(Name name, Scope parent, CType type) { LocalVariableSymbol sym = (LocalVariableSymbol)NewBasicSymbol(SYMKIND.SK_LocalVariableSymbol, name, parent); sym.SetType(type); @@ -149,25 +120,25 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return sym; } - public MethodSymbol CreateMethod(Name name, AggregateSymbol parent) => + public static MethodSymbol CreateMethod(Name name, AggregateSymbol parent) => NewBasicSymbol(SYMKIND.SK_MethodSymbol, name, parent) as MethodSymbol; - public PropertySymbol CreateProperty(Name name, AggregateSymbol parent) + public static PropertySymbol CreateProperty(Name name, AggregateSymbol parent) { PropertySymbol sym = NewBasicSymbol(SYMKIND.SK_PropertySymbol, name, parent) as PropertySymbol; Debug.Assert(sym != null); - return (sym); + return sym; } - public EventSymbol CreateEvent(Name name, AggregateSymbol parent) + public static EventSymbol CreateEvent(Name name, AggregateSymbol parent) { EventSymbol sym = NewBasicSymbol(SYMKIND.SK_EventSymbol, name, parent) as EventSymbol; Debug.Assert(sym != null); - return (sym); + return sym; } - public TypeParameterSymbol CreateMethodTypeParameter(Name pName, MethodSymbol pParent, int index, int indexTotal) + public static TypeParameterSymbol CreateMethodTypeParameter(Name pName, MethodSymbol pParent, int index, int indexTotal) { TypeParameterSymbol pResult = (TypeParameterSymbol)NewBasicSymbol(SYMKIND.SK_TypeParameterSymbol, pName, pParent); pResult.SetIndexInOwnParameters(index); @@ -179,7 +150,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pResult; } - public TypeParameterSymbol CreateClassTypeParameter(Name pName, AggregateSymbol pParent, int index, int indexTotal) + public static TypeParameterSymbol CreateClassTypeParameter(Name pName, AggregateSymbol pParent, int index, int indexTotal) { TypeParameterSymbol pResult = (TypeParameterSymbol)NewBasicSymbol(SYMKIND.SK_TypeParameterSymbol, pName, pParent); pResult.SetIndexInOwnParameters(index); @@ -191,9 +162,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pResult; } - public Scope CreateScope() => (Scope)NewBasicSymbol(SYMKIND.SK_Scope, null, null); + public static Scope CreateScope() => (Scope)NewBasicSymbol(SYMKIND.SK_Scope, null, null); - public IndexerSymbol CreateIndexer(Name name, ParentSymbol parent, Name realName) + public static IndexerSymbol CreateIndexer(Name name, ParentSymbol parent) { IndexerSymbol sym = (IndexerSymbol)NewBasicSymbol(SYMKIND.SK_IndexerSymbol, name, parent); sym.setKind(SYMKIND.SK_PropertySymbol); diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/Symbol.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/Symbol.cs index aa60a26..6686640 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/Symbol.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/Symbol.cs @@ -68,6 +68,19 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public Symbol nextChild; // next child of this parent public Symbol nextSameName; // next child of this parent with same name. + public Symbol LookupNext(symbmask_t kindmask) + { + // Keep traversing the list of symbols with same name and parent. + for (Symbol sym = nextSameName; sym != null; sym = sym.nextSameName) + { + if ((kindmask & sym.mask()) != 0) + { + return sym; + } + } + + return null; + } public ACCESS GetAccess() { @@ -149,10 +162,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics case SYMKIND.SK_TypeParameterSymbol: return ((AggregateSymbol)parent).AssociatedAssembly; - case SYMKIND.SK_AggregateDeclaration: - return ((AggregateDeclaration)this).GetAssembly(); case SYMKIND.SK_AggregateSymbol: return ((AggregateSymbol)this).AssociatedAssembly; + default: // Should never call this with any other kind. Debug.Assert(false, "GetAssemblyID called on bad sym kind"); @@ -174,8 +186,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics case SYMKIND.SK_TypeParameterSymbol: return ((AggregateSymbol)parent).InternalsVisibleTo(assembly); - case SYMKIND.SK_AggregateDeclaration: - return ((AggregateDeclaration)this).Agg().InternalsVisibleTo(assembly); case SYMKIND.SK_AggregateSymbol: return ((AggregateSymbol)this).InternalsVisibleTo(assembly); default: diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolKind.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolKind.cs index a512d7a..57bc070 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolKind.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolKind.cs @@ -8,7 +8,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { SK_NamespaceSymbol, SK_AggregateSymbol, - SK_AggregateDeclaration, SK_TypeParameterSymbol, SK_FieldSymbol, SK_LocalVariableSymbol, diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolLoader.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolLoader.cs index 7ae8ab5..cc441db 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolLoader.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolLoader.cs @@ -3,99 +3,17 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using Microsoft.CSharp.RuntimeBinder.Errors; using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class SymbolLoader + internal static class SymbolLoader { - private PredefinedMembers PredefinedMembers { get; } - private GlobalSymbolContext GlobalSymbolContext { get; } - public ErrorHandling ErrorContext { get; } - public SymbolTable RuntimeBinderSymbolTable { get; private set; } + public static AggregateSymbol GetPredefAgg(PredefinedType pt) => TypeManager.GetPredefAgg(pt); - public SymbolLoader() - { - GlobalSymbolContext globalSymbols = new GlobalSymbolContext(); - PredefinedMembers = new PredefinedMembers(this); - ErrorContext = new ErrorHandling(globalSymbols); - GlobalSymbolContext = globalSymbols; - Debug.Assert(GlobalSymbolContext != null); - } - - public ErrorHandling GetErrorContext() - { - return ErrorContext; - } - - public GlobalSymbolContext GetGlobalSymbolContext() - { - return GlobalSymbolContext; - } - - public PredefinedTypes GetPredefindTypes() - { - return GlobalSymbolContext.GetPredefTypes(); - } + public static AggregateType GetPredefindType(PredefinedType pt) => GetPredefAgg(pt).getThisType(); - public TypeManager GetTypeManager() - { - return TypeManager; - } - - public TypeManager TypeManager - { - get { return GlobalSymbolContext.TypeManager; } - } - - public PredefinedMembers getPredefinedMembers() - { - return PredefinedMembers; - } - - public BSYMMGR getBSymmgr() - { - return GlobalSymbolContext.GetGlobalSymbols(); - } - - public SymFactory GetGlobalSymbolFactory() - { - return GlobalSymbolContext.GetGlobalSymbolFactory(); - } - - public AggregateSymbol GetPredefAgg(PredefinedType pt) => GetTypeManager().GetPredefAgg(pt); - - public AggregateType GetPredefindType(PredefinedType pt) => GetPredefAgg(pt).getThisType(); - - public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) - { - return getBSymmgr().LookupAggMember(name, agg, mask); - } - - public static Symbol LookupNextSym(Symbol sym, ParentSymbol parent, symbmask_t kindmask) - => BSYMMGR.LookupNextSym(sym, parent, kindmask); - - // It would be nice to make this a virtual method on typeSym. - public AggregateType GetAggTypeSym(CType typeSym) - { - Debug.Assert(typeSym != null); - Debug.Assert(typeSym is AggregateType || - typeSym is ArrayType || - typeSym is NullableType); - - switch (typeSym.TypeKind) - { - case TypeKind.TK_AggregateType: - return (AggregateType)typeSym; - case TypeKind.TK_ArrayType: - return GetPredefindType(PredefinedType.PT_ARRAY); - case TypeKind.TK_NullableType: - return ((NullableType)typeSym).GetAts(); - } - Debug.Assert(false, "Bad typeSym!"); - return null; - } + public static Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) => SymbolStore.LookupSym(name, agg, mask); private static bool IsBaseInterface(AggregateType atsDer, AggregateType pBase) { @@ -167,7 +85,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - private bool HasCovariantArrayConversion(ArrayType pSource, ArrayType pDest) + private static bool HasCovariantArrayConversion(ArrayType pSource, ArrayType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -178,7 +96,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics HasImplicitReferenceConversion(pSource.ElementType, pDest.ElementType); } - public bool HasIdentityOrImplicitReferenceConversion(CType pSource, CType pDest) + public static bool HasIdentityOrImplicitReferenceConversion(CType pSource, CType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -192,7 +110,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics private static bool AreTypesEqualForConversion(CType pType1, CType pType2) => pType1.Equals(pType2); - private bool HasArrayConversionToInterface(ArrayType pSource, CType pDest) + private static bool HasArrayConversionToInterface(ArrayType pSource, CType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -233,7 +151,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return HasIdentityOrImplicitReferenceConversion(pSource.ElementType, atsDest.TypeArgsAll[0]); } - private bool HasImplicitReferenceConversion(CType pSource, CType pDest) + private static bool HasImplicitReferenceConversion(CType pSource, CType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -277,7 +195,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // convertible to T. // * From any interface type S to any interface type T provided S implements an interface // convertible to T. - // * From any interface type S to any interface type T provided S is not T and S is + // * From any interface type S to any interface type T provided S is not T and S is // an interface convertible to T. return HasAnyBaseInterfaceConversion(aggSource, aggDest); @@ -300,7 +218,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // The spec should actually say // - // * From any delegate type to System.Delegate + // * From any delegate type to System.Delegate // * From any delegate type to System.MulticastDelegate // * From any delegate type to any interface implemented by System.MulticastDelegate if (aggDest.IsPredefType(PredefinedType.PT_MULTIDEL) @@ -359,7 +277,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - private bool HasAnyBaseInterfaceConversion(CType pDerived, CType pBase) + private static bool HasAnyBaseInterfaceConversion(CType pDerived, CType pBase) { if (!pBase.IsInterfaceType || !(pDerived is AggregateType atsDer)) { @@ -386,7 +304,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// // The rules for variant interface and delegate conversions are the same: // - // An interface/delegate type S is convertible to an interface/delegate type T + // An interface/delegate type S is convertible to an interface/delegate type T // if and only if T is U and T is U such that for all // parameters of U: // @@ -396,7 +314,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // * if the ith parameter of U is contravariant then either Si is exactly // equal to Ti, or there is an implicit reference conversion from Ti to Si. - private bool HasInterfaceConversion(AggregateType pSource, AggregateType pDest) + private static bool HasInterfaceConversion(AggregateType pSource, AggregateType pDest) { Debug.Assert(pSource != null && pSource.IsInterfaceType); Debug.Assert(pDest != null && pDest.IsInterfaceType); @@ -405,7 +323,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ////////////////////////////////////////////////////////////////////////////// - private bool HasDelegateConversion(AggregateType pSource, AggregateType pDest) + private static bool HasDelegateConversion(AggregateType pSource, AggregateType pDest) { Debug.Assert(pSource != null && pSource.IsDelegateType); Debug.Assert(pDest != null && pDest.IsDelegateType); @@ -414,7 +332,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics ////////////////////////////////////////////////////////////////////////////// - private bool HasVariantConversion(AggregateType pSource, AggregateType pDest) + private static bool HasVariantConversion(AggregateType pSource, AggregateType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -422,6 +340,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { return true; } + AggregateSymbol pAggSym = pSource.OwningAggregate; if (pAggSym != pDest.OwningAggregate) { @@ -467,7 +386,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - private bool HasImplicitBoxingConversion(CType pSource, CType pDest) + private static bool HasImplicitBoxingConversion(CType pSource, CType pDest) { Debug.Assert(pSource != null); Debug.Assert(pDest != null); @@ -504,7 +423,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return IsBaseClass(pSource, pDest) || HasAnyBaseInterfaceConversion(pSource, pDest); } - public bool HasBaseConversion(CType pSource, CType pDest) + public static bool HasBaseConversion(CType pSource, CType pDest) { // By a "base conversion" we mean: // @@ -515,9 +434,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // In other words, these are conversions that can be made to a base // class, base interface or co/contravariant type without any change in - // representation other than boxing. A conversion from, say, int to double, + // representation other than boxing. A conversion from, say, int to double, // is NOT a "base conversion", because representation is changed. A conversion - // from, say, lambda to expression tree is not a "base conversion" because + // from, say, lambda to expression tree is not a "base conversion" because // do not have a type. // // The existence of a base conversion depends solely upon the source and @@ -590,11 +509,5 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - - internal void SetSymbolTable(SymbolTable symbolTable) - { - RuntimeBinderSymbolTable = symbolTable; - } } } - diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolManagerBase.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolManagerBase.cs deleted file mode 100644 index 8d61c6b..0000000 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolManagerBase.cs +++ /dev/null @@ -1,304 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using Microsoft.CSharp.RuntimeBinder.Syntax; - -namespace Microsoft.CSharp.RuntimeBinder.Semantics -{ - internal sealed class BSYMMGR - { - // Special nullable members. - public PropertySymbol propNubValue; - public MethodSymbol methNubCtor; - - private readonly SymFactory _symFactory; - - private SYMTBL tableGlobal; - - // The hash table for type arrays. - private Dictionary tableTypeArrays; - - private static readonly TypeArray s_taEmpty = new TypeArray(Array.Empty()); - - public BSYMMGR() - { - this.tableGlobal = new SYMTBL(); - _symFactory = new SymFactory(this.tableGlobal); - - this.tableTypeArrays = new Dictionary(); - - //////////////////////////////////////////////////////////////////////////////// - // Build the data structures needed to make FPreLoad fast. Make sure the - // namespaces are created. Compute and sort hashes of the NamespaceSymbol * value and type - // name (sans arity indicator). - - for (int i = 0; i < (int)PredefinedType.PT_COUNT; ++i) - { - NamespaceSymbol ns = NamespaceSymbol.Root; - string name = PredefinedTypeFacts.GetName((PredefinedType)i); - int start = 0; - while (start < name.Length) - { - int iDot = name.IndexOf('.', start); - if (iDot == -1) - break; - string sub = (iDot > start) ? name.Substring(start, iDot - start) : name.Substring(start); - Name nm = NameManager.Add(sub); - ns = LookupGlobalSymCore(nm, ns, symbmask_t.MASK_NamespaceSymbol) as NamespaceSymbol ?? _symFactory.CreateNamespace(nm, ns); - start += sub.Length + 1; - } - } - } - - public SYMTBL GetSymbolTable() - { - return tableGlobal; - } - - public static TypeArray EmptyTypeArray() - { - return s_taEmpty; - } - - public BetterType CompareTypes(TypeArray ta1, TypeArray ta2) - { - if (ta1 == ta2) - { - return BetterType.Same; - } - if (ta1.Count != ta2.Count) - { - // The one with more parameters is more specific. - return ta1.Count > ta2.Count ? BetterType.Left : BetterType.Right; - } - - BetterType nTot = BetterType.Neither; - - for (int i = 0; i < ta1.Count; i++) - { - CType type1 = ta1[i]; - CType type2 = ta2[i]; - BetterType nParam = BetterType.Neither; - - LAgain: - if (type1.TypeKind != type2.TypeKind) - { - if (type1 is TypeParameterType) - { - nParam = BetterType.Right; - } - else if (type2 is TypeParameterType) - { - nParam = BetterType.Left; - } - } - else - { - switch (type1.TypeKind) - { - default: - Debug.Assert(false, "Bad kind in CompareTypes"); - break; - case TypeKind.TK_TypeParameterType: - break; - - case TypeKind.TK_PointerType: - case TypeKind.TK_ParameterModifierType: - case TypeKind.TK_ArrayType: - case TypeKind.TK_NullableType: - type1 = type1.BaseOrParameterOrElementType; - type2 = type2.BaseOrParameterOrElementType; - goto LAgain; - - case TypeKind.TK_AggregateType: - nParam = CompareTypes(((AggregateType)type1).TypeArgsAll, ((AggregateType)type2).TypeArgsAll); - break; - } - } - - if (nParam == BetterType.Right || nParam == BetterType.Left) - { - if (nTot == BetterType.Same || nTot == BetterType.Neither) - { - nTot = nParam; - } - else if (nParam != nTot) - { - return BetterType.Neither; - } - } - } - - return nTot; - } - - public SymFactory GetSymFactory() - { - return _symFactory; - } - - public Symbol LookupGlobalSymCore(Name name, ParentSymbol parent, symbmask_t kindmask) - { - return tableGlobal.LookupSym(name, parent, kindmask); - } - - public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) - { - return tableGlobal.LookupSym(name, agg, mask); - } - - public static Symbol LookupNextSym(Symbol sym, ParentSymbol parent, symbmask_t kindmask) - { - Debug.Assert(sym.parent == parent); - - sym = sym.nextSameName; - Debug.Assert(sym == null || sym.parent == parent); - - // Keep traversing the list of symbols with same name and parent. - while (sym != null) - { - if ((kindmask & sym.mask()) > 0) - return sym; - - sym = sym.nextSameName; - Debug.Assert(sym == null || sym.parent == parent); - } - - return null; - } - - //////////////////////////////////////////////////////////////////////////////// - // Allocate a type array; used to represent a parameter list. - // We use a hash table to make sure that allocating the same type array twice - // returns the same value. This does two things: - // - // 1) Save a lot of memory. - // 2) Make it so parameter lists can be compared by a simple pointer comparison - // 3) Allow us to associate a token with each signature for faster metadata emit - - private readonly struct TypeArrayKey : IEquatable - { - private readonly CType[] _types; - private readonly int _hashCode; - - public TypeArrayKey(CType[] types) - { - _types = types; - int hashCode = 0x162A16FE; - foreach (CType type in types) - { - hashCode = (hashCode << 5) - hashCode; - if (type != null) - { - hashCode ^= type.GetHashCode(); - } - } - - _hashCode = hashCode; - } - - public bool Equals(TypeArrayKey other) - { - CType[] types = _types; - CType[] otherTypes = other._types; - if (otherTypes == types) - { - return true; - } - - if (other._hashCode != _hashCode || otherTypes.Length != types.Length) - { - return false; - } - - for (int i = 0; i < types.Length; i++) - { - if (types[i] != otherTypes[i]) - { - return false; - } - } - - return true; - } - -#if DEBUG - [ExcludeFromCodeCoverage] // Typed overload should always be the method called. -#endif - public override bool Equals(object obj) - { - Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); - return obj is TypeArrayKey && Equals((TypeArrayKey)obj); - } - - public override int GetHashCode() - { - return _hashCode; - } - } - - public TypeArray AllocParams(int ctype, CType[] prgtype) - { - if (ctype == 0) - { - return s_taEmpty; - } - Debug.Assert(ctype == prgtype.Length); - return AllocParams(prgtype); - } - - public TypeArray AllocParams(int ctype, TypeArray array, int offset) - { - if (ctype == 0) - { - return s_taEmpty; - } - - if (ctype == array.Count) - { - return array; - } - - CType[] types = array.Items; - CType[] newTypes = new CType[ctype]; - Array.ConstrainedCopy(types, offset, newTypes, 0, ctype); - return AllocParams(newTypes); - } - - public TypeArray AllocParams(params CType[] types) - { - if (types == null || types.Length == 0) - { - return s_taEmpty; - } - TypeArrayKey key = new TypeArrayKey(types); - TypeArray result; - if (!tableTypeArrays.TryGetValue(key, out result)) - { - result = new TypeArray(types); - tableTypeArrays.Add(key, result); - } - return result; - } - - private TypeArray ConcatParams(CType[] prgtype1, CType[] prgtype2) - { - CType[] combined = new CType[prgtype1.Length + prgtype2.Length]; - Array.Copy(prgtype1, 0, combined, 0, prgtype1.Length); - Array.Copy(prgtype2, 0, combined, prgtype1.Length, prgtype2.Length); - return AllocParams(combined); - } - - public TypeArray ConcatParams(TypeArray pta1, TypeArray pta2) - { - return ConcatParams(pta1.Items, pta2.Items); - } - } -} - diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolTable.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolStore.cs similarity index 63% rename from src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolTable.cs rename to src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolStore.cs index 5ec3c3b..243bd07 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolTable.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolStore.cs @@ -13,30 +13,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // A symbol table is a helper class used by the symbol manager. There are // two symbol tables; a global and a local. - internal sealed class SYMTBL + internal static class SymbolStore { - ///////////////////////////////////////////////////////////////////////////////// - // Public + private static readonly Dictionary s_dictionary = new Dictionary(); - public SYMTBL() - { - _dictionary = new Dictionary(); - } + public static Symbol LookupSym(Name name, ParentSymbol parent, symbmask_t kindmask) => + s_dictionary.TryGetValue(new Key(name, parent), out Symbol sym) ? FindCorrectKind(sym, kindmask) : null; - public Symbol LookupSym(Name name, ParentSymbol parent, symbmask_t kindmask) - { - Key k = new Key(name, parent); - Symbol sym; - - if (_dictionary.TryGetValue(k, out sym)) - { - return FindCorrectKind(sym, kindmask); - } - - return null; - } - - public void InsertChild(ParentSymbol parent, Symbol child) + public static void InsertChild(ParentSymbol parent, Symbol child) { Debug.Assert(child.nextSameName == null); Debug.Assert(child.parent == null || child.parent == parent); @@ -46,7 +30,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics InsertChildNoGrow(child); } - private void InsertChildNoGrow(Symbol child) + private static void InsertChildNoGrow(Symbol child) { switch (child.getKind()) { @@ -55,10 +39,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return; } - Key k = new Key(child.name, child.parent); - Symbol sym; - - if (_dictionary.TryGetValue(k, out sym)) + if (s_dictionary.TryGetValue(new Key(child.name, child.parent), out Symbol sym)) { // Link onto the end of the symbol chain here. while (sym?.nextSameName != null) @@ -71,7 +52,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } else { - _dictionary.Add(k, child); + s_dictionary.Add(new Key(child.name, child.parent), child); } } @@ -83,15 +64,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { return sym; } + sym = sym.nextSameName; } while (sym != null); return null; } - private readonly Dictionary _dictionary; - - private sealed class Key : IEquatable + private readonly struct Key : IEquatable { private readonly Name _name; private readonly ParentSymbol _parent; @@ -102,21 +82,18 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics _parent = parent; } - public bool Equals(Key other) => other != null && _name.Equals(other._name) && _parent.Equals(other._parent); + public bool Equals(Key other) => _name == other._name && _parent == other._parent; -#if DEBUG +#if DEBUG [ExcludeFromCodeCoverage] // Typed overload should always be the method called. #endif public override bool Equals(object obj) { Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); - return Equals(obj as Key); + return obj is Key key && Equals(key); } - public override int GetHashCode() - { - return _name.GetHashCode() ^ _parent.GetHashCode(); - } + public override int GetHashCode() => _name.GetHashCode() ^ _parent.GetHashCode(); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Cast.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Cast.cs index eed4a2b..fc4c67f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Cast.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Cast.cs @@ -20,5 +20,19 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public Expr Argument { get; set; } public bool IsBoxingCast => (Flags & (EXPRFLAG.EXF_BOX | EXPRFLAG.EXF_FORCE_BOX)) != 0; + + public override object Object + { + get + { + Expr arg = Argument; + while (arg is ExprCast castArg) + { + arg = castArg.Argument; + } + + return arg.Object; + } + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Constant.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Constant.cs index 53a67ec..0454d39 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Constant.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Constant.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Diagnostics; namespace Microsoft.CSharp.RuntimeBinder.Semantics @@ -44,5 +45,68 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } } + + public override object Object + { + get + { + if (Type is NullType) + { + return null; + } + + object objval; + switch (System.Type.GetTypeCode(Type.AssociatedSystemType)) + { + case TypeCode.Boolean: + objval = Val.BooleanVal; + break; + case TypeCode.SByte: + objval = Val.SByteVal; + break; + case TypeCode.Byte: + objval = Val.ByteVal; + break; + case TypeCode.Int16: + objval = Val.Int16Val; + break; + case TypeCode.UInt16: + objval = Val.UInt16Val; + break; + case TypeCode.Int32: + objval = Val.Int32Val; + break; + case TypeCode.UInt32: + objval = Val.UInt32Val; + break; + case TypeCode.Int64: + objval = Val.Int64Val; + break; + case TypeCode.UInt64: + objval = Val.UInt64Val; + break; + case TypeCode.Single: + objval = Val.SingleVal; + break; + case TypeCode.Double: + objval = Val.DoubleVal; + break; + case TypeCode.Decimal: + objval = Val.DecimalVal; + break; + case TypeCode.Char: + objval = Val.CharVal; + break; + case TypeCode.String: + objval = Val.StringVal; + break; + default: + objval = Val.ObjectVal; + break; + } + + return Type.IsEnumType ? Enum.ToObject(Type.AssociatedSystemType, objval) : objval; + } + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs index eb7223b..f1ef38f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.CSharp.RuntimeBinder.Semantics { @@ -37,5 +38,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } protected set { _type = value; } } + + [ExcludeFromCodeCoverage] // Should only be called through override. + public virtual object Object + { + get + { + Debug.Fail("Invalid Expr in GetObject"); + throw Error.InternalCompilerError(); + } + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExprWithType.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExprWithType.cs index f9ac7c1..cdc7871 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExprWithType.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ExprWithType.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; + namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal abstract class ExprWithType : Expr @@ -11,5 +13,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Type = type; } + + protected static bool TypesAreEqual(Type t1, Type t2) => t1 == t2 || t1.IsEquivalentTo(t2); } -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MemberGroup.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MemberGroup.cs index 49e456b..bb946d1 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MemberGroup.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MemberGroup.cs @@ -9,7 +9,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal sealed class ExprMemberGroup : ExprWithType { - public ExprMemberGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol pMPS, Expr optionalObject, CMemberLookupResults memberLookupResults) + public ExprMemberGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, Expr optionalObject, CMemberLookupResults memberLookupResults) : base(ExpressionKind.MemberGroup, MethodGroupType.Instance) { Debug.Assert( @@ -18,7 +18,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics | EXPRFLAG.EXF_MASK_ANY)) == 0); Flags = flags; Name = name; - TypeArgs = typeArgs ?? BSYMMGR.EmptyTypeArray(); + TypeArgs = typeArgs ?? TypeArray.Empty; SymKind = symKind; ParentType = parentType; OptionalObject = optionalObject; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MethodInfo.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MethodInfo.cs index 4f166c4..b2db9fd 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MethodInfo.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/MethodInfo.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Diagnostics; +using System.Reflection; namespace Microsoft.CSharp.RuntimeBinder.Semantics { @@ -17,5 +19,137 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } public MethWithInst Method { get; } + + public MethodInfo MethodInfo + { + get + { + // To do this, we need to construct a type array of the parameter types, + // get the parent constructed type, and get the method from it. + AggregateType aggType = Method.Ats; + MethodSymbol methSym = Method.Meth(); + + TypeArray genericParams = TypeManager.SubstTypeArray(methSym.Params, aggType, methSym.typeVars); + CType genericReturn = TypeManager.SubstType(methSym.RetType, aggType, methSym.typeVars); + + Type type = aggType.AssociatedSystemType; + MethodInfo methodInfo = methSym.AssociatedMemberInfo as MethodInfo; + + // This is to ensure that for embedded nopia types, we have the + // appropriate local type from the member itself; this is possible + // because nopia types are not generic or nested. + if (!type.IsGenericType && !type.IsNested) + { + type = methodInfo.DeclaringType; + } + + // We need to find the associated methodinfo on the instantiated type. + foreach (MethodInfo m in type.GetRuntimeMethods()) + { +#if UNSUPPORTEDAPI + if ((m.MetadataToken != methodInfo.MetadataToken) || (m.Module != methodInfo.Module)) +#else + if (!m.HasSameMetadataDefinitionAs(methodInfo)) +#endif + { + continue; + } + + Debug.Assert(m.Name == methodInfo.Name && + m.GetParameters().Length == genericParams.Count && + TypesAreEqual(m.ReturnType, genericReturn.AssociatedSystemType)); + + bool match = true; + ParameterInfo[] parameters = m.GetParameters(); + for (int i = 0; i < genericParams.Count; i++) + { + if (!TypesAreEqual(parameters[i].ParameterType, genericParams[i].AssociatedSystemType)) + { + match = false; + break; + } + } + + if (match) + { + if (m.IsGenericMethod) + { + int size = Method.TypeArgs?.Count ?? 0; + Type[] typeArgs = new Type[size]; + if (size > 0) + { + for (int i = 0; i < Method.TypeArgs.Count; i++) + { + typeArgs[i] = Method.TypeArgs[i].AssociatedSystemType; + } + } + + return m.MakeGenericMethod(typeArgs); + } + + return m; + } + } + + throw Error.InternalCompilerError(); + } + } + + public ConstructorInfo ConstructorInfo + { + get + { + // To do this, we need to construct a type array of the parameter types, + // get the parent constructed type, and get the method from it. + AggregateType aggType = Method.Ats; + MethodSymbol methSym = Method.Meth(); + + TypeArray genericInstanceParams = TypeManager.SubstTypeArray(methSym.Params, aggType); + Type type = aggType.AssociatedSystemType; + ConstructorInfo ctorInfo = (ConstructorInfo)methSym.AssociatedMemberInfo; + + // This is to ensure that for embedded nopia types, we have the + // appropriate local type from the member itself; this is possible + // because nopia types are not generic or nested. + if (!type.IsGenericType && !type.IsNested) + { + type = ctorInfo.DeclaringType; + } + + foreach (ConstructorInfo c in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) + { +#if UNSUPPORTEDAPI + if ((c.MetadataToken != ctorInfo.MetadataToken) || (c.Module != ctorInfo.Module)) +#else + if (!c.HasSameMetadataDefinitionAs(ctorInfo)) +#endif + { + continue; + } + + Debug.Assert(c.GetParameters() == null || c.GetParameters().Length == genericInstanceParams.Count); + + bool match = true; + ParameterInfo[] parameters = c.GetParameters(); + for (int i = 0; i < genericInstanceParams.Count; i++) + { + if (!TypesAreEqual(parameters[i].ParameterType, genericInstanceParams[i].AssociatedSystemType)) + { + match = false; + break; + } + } + + if (match) + { + return c; + } + } + + throw Error.InternalCompilerError(); + } + } + + public override object Object => MethodInfo; } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/PropertyInfo.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/PropertyInfo.cs index 755228a..5b439c1 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/PropertyInfo.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/PropertyInfo.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Diagnostics; +using System.Reflection; namespace Microsoft.CSharp.RuntimeBinder.Semantics { @@ -17,5 +19,62 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } public PropWithType Property { get; } + + public PropertyInfo PropertyInfo + { + get + { + // To do this, we need to construct a type array of the parameter types, + // get the parent constructed type, and get the property from it. + AggregateType aggType = Property.Ats; + PropertySymbol propSym = Property.Prop(); + + TypeArray genericInstanceParams = TypeManager.SubstTypeArray(propSym.Params, aggType, null); + + Type type = aggType.AssociatedSystemType; + PropertyInfo propertyInfo = propSym.AssociatedPropertyInfo; + + // This is to ensure that for embedded nopia types, we have the + // appropriate local type from the member itself; this is possible + // because nopia types are not generic or nested. + if (!type.IsGenericType && !type.IsNested) + { + type = propertyInfo.DeclaringType; + } + + foreach (PropertyInfo p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) + { +#if UNSUPPORTEDAPI + if ((p.MetadataToken != propertyInfo.MetadataToken) || (p.Module != propertyInfo.Module)) +#else + if (!p.HasSameMetadataDefinitionAs(propertyInfo)) + { +#endif + continue; + } + Debug.Assert((p.Name == propertyInfo.Name) && + (p.GetIndexParameters() == null || p.GetIndexParameters().Length == genericInstanceParams.Count)); + + bool match = true; + ParameterInfo[] parameters = p.GetSetMethod(true) != null ? + p.GetSetMethod(true).GetParameters() : p.GetGetMethod(true).GetParameters(); + for (int i = 0; i < genericInstanceParams.Count; i++) + { + if (!TypesAreEqual(parameters[i].ParameterType, genericInstanceParams[i].AssociatedSystemType)) + { + match = false; + break; + } + } + + if (match) + { + return p; + } + } + + throw Error.InternalCompilerError(); + } + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/TypeOf.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/TypeOf.cs index 8e4bbe1..2ab3e13 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/TypeOf.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/TypeOf.cs @@ -14,5 +14,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } public CType SourceType { get; } + + public override object Object => SourceType.AssociatedSystemType; } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs index 0056f4b..58d8e39 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Visitors/ExpressionTreeRewriter.cs @@ -9,21 +9,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal sealed class ExpressionTreeRewriter : ExprVisitorBase { - public static ExprBinOp Rewrite(ExprBoundLambda expr, ExprFactory expressionFactory, SymbolLoader symbolLoader) => - new ExpressionTreeRewriter(expressionFactory, symbolLoader).VisitBoundLambda(expr); - - private ExprFactory expressionFactory; - private SymbolLoader symbolLoader; - - private ExprFactory GetExprFactory() { return expressionFactory; } - - private SymbolLoader GetSymbolLoader() { return symbolLoader; } - - private ExpressionTreeRewriter(ExprFactory expressionFactory, SymbolLoader symbolLoader) - { - this.expressionFactory = expressionFactory; - this.symbolLoader = symbolLoader; - } + public static ExprBinOp Rewrite(ExprBoundLambda expr) => new ExpressionTreeRewriter().VisitBoundLambda(expr); protected override Expr Dispatch(Expr expr) { @@ -60,7 +46,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // // The LHS becomes Expression.Property(instance, indexerInfo, arguments). Expr instance = Visit(prop.MemberGroup.OptionalObject); - Expr propInfo = GetExprFactory().CreatePropertyInfo(prop.PropWithTypeSlot.Prop(), prop.PropWithTypeSlot.Ats); + Expr propInfo = ExprFactory.CreatePropertyInfo(prop.PropWithTypeSlot.Prop(), prop.PropWithTypeSlot.Ats); Expr arguments = GenerateParamsArray( GenerateArgsList(prop.OptionalArguments), PredefinedType.PT_EXPRESSION); @@ -96,8 +82,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics MethodSymbol lambdaMethod = GetPreDefMethod(PREDEFMETH.PM_EXPRESSION_LAMBDA); AggregateType delegateType = anonmeth.DelegateType; - TypeArray lambdaTypeParams = GetSymbolLoader().getBSymmgr().AllocParams(1, new CType[] { delegateType }); - AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); + TypeArray lambdaTypeParams = TypeArray.Allocate(delegateType); + AggregateType expressionType = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION); MethWithInst mwi = new MethWithInst(lambdaMethod, expressionType, lambdaTypeParams); Expr createParameters = CreateWraps(anonmeth); Debug.Assert(createParameters != null); @@ -105,12 +91,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr body = Visit(anonmeth.Expression); Debug.Assert(anonmeth.ArgumentScope.nextChild == null); Expr parameters = GenerateParamsArray(null, PredefinedType.PT_PARAMETEREXPRESSION); - Expr args = GetExprFactory().CreateList(body, parameters); - CType typeRet = GetSymbolLoader().GetTypeManager().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall call = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, mwi); + Expr args = ExprFactory.CreateList(body, parameters); + CType typeRet = TypeManager.SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall call = ExprFactory.CreateCall(0, typeRet, args, pMemGroup, mwi); call.PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA; - return GetExprFactory().CreateSequence(createParameters, call); + return ExprFactory.CreateSequence(createParameters, call); } protected override Expr VisitCONSTANT(ExprConstant expr) { @@ -129,13 +115,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr pObject; if (expr.OptionalObject== null) { - pObject = GetExprFactory().CreateNull(); + pObject = ExprFactory.CreateNull(); } else { pObject = Visit(expr.OptionalObject); } - ExprFieldInfo pFieldInfo = GetExprFactory().CreateFieldInfo(expr.FieldWithType.Field(), expr.FieldWithType.GetType()); + ExprFieldInfo pFieldInfo = ExprFactory.CreateFieldInfo(expr.FieldWithType.Field(), expr.FieldWithType.GetType()); return GenerateCall(PREDEFMETH.PM_EXPRESSION_FIELD, pObject, pFieldInfo); } protected override Expr VisitUSERDEFINEDCONVERSION(ExprUserDefinedConversion expr) @@ -153,7 +139,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // we can omit the cast. if (pArgument.Type == pExpr.Type || SymbolLoader.IsBaseClassOfClass(pArgument.Type, pExpr.Type) || - CConversions.FImpRefConv(GetSymbolLoader(), pArgument.Type, pExpr.Type)) + CConversions.FImpRefConv(pArgument.Type, pExpr.Type)) { return Visit(pArgument); } @@ -190,7 +176,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr p1 = Visit(expr.FirstArgument); Expr p2 = Visit(expr.SecondArgument); MethodSymbol method = GetPreDefMethod(pdm); - Expr methodInfo = GetExprFactory().CreateMethodInfo(method, GetSymbolLoader().GetPredefindType(PredefinedType.PT_STRING), null); + Expr methodInfo = ExprFactory.CreateMethodInfo(method, SymbolLoader.GetPredefindType(PredefinedType.PT_STRING), null); return GenerateCall(PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED, p1, p2, methodInfo); } protected override Expr VisitBINOP(ExprBinOp expr) @@ -260,7 +246,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr pObject; if (expr.MethWithInst.Meth().isStatic || expr.MemberGroup.OptionalObject== null) { - pObject = GetExprFactory().CreateNull(); + pObject = ExprFactory.CreateNull(); } else { @@ -285,7 +271,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } pObject = Visit(pObject); } - Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.MethWithInst); + Expr methodInfo = ExprFactory.CreateMethodInfo(expr.MethWithInst); Expr args = GenerateArgsList(expr.OptionalArguments); Expr Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); PREDEFMETH pdm = PREDEFMETH.PM_EXPRESSION_CALL; @@ -299,13 +285,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr pObject; if (expr.PropWithTypeSlot.Prop().isStatic || expr.MemberGroup.OptionalObject== null) { - pObject = GetExprFactory().CreateNull(); + pObject = ExprFactory.CreateNull(); } else { pObject = Visit(expr.MemberGroup.OptionalObject); } - Expr propInfo = GetExprFactory().CreatePropertyInfo(expr.PropWithTypeSlot.Prop(), expr.PropWithTypeSlot.GetType()); + Expr propInfo = ExprFactory.CreatePropertyInfo(expr.PropWithTypeSlot.Prop(), expr.PropWithTypeSlot.GetType()); if (expr.OptionalArguments != null) { // It is an indexer property. Turn it into a virtual method call. @@ -403,28 +389,28 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { // We have already inserted casts if not lifted, so we should never see an enum. Debug.Assert(expr.IsLifted); - convertL = GetSymbolLoader().GetTypeManager().GetNullable(typeL.UnderlyingEnumType); + convertL = TypeManager.GetNullable(typeL.UnderlyingEnumType); typeL = convertL; didEnumConversion = true; } else if (typeL is NullableType nubL && nubL.UnderlyingType.IsEnumType) { Debug.Assert(expr.IsLifted); - convertL = GetSymbolLoader().GetTypeManager().GetNullable(nubL.UnderlyingType.UnderlyingEnumType); + convertL = TypeManager.GetNullable(nubL.UnderlyingType.UnderlyingEnumType); typeL = convertL; didEnumConversion = true; } if (typeR.IsEnumType) { Debug.Assert(expr.IsLifted); - convertR = GetSymbolLoader().GetTypeManager().GetNullable(typeR.UnderlyingEnumType); + convertR = TypeManager.GetNullable(typeR.UnderlyingEnumType); typeR = convertR; didEnumConversion = true; } else if (typeR is NullableType nubR && nubR.UnderlyingType.IsEnumType) { Debug.Assert(expr.IsLifted); - convertR = GetSymbolLoader().GetTypeManager().GetNullable(nubR.UnderlyingType.UnderlyingEnumType); + convertR = TypeManager.GetNullable(nubR.UnderlyingType.UnderlyingEnumType); typeR = convertR; didEnumConversion = true; } @@ -546,7 +532,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics p1 = Visit(p1); p2 = Visit(p2); FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2); - Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.UserDefinedCallMethod); + Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod); Expr call = GenerateCall(pdm, p1, p2, methodInfo); // Delegate add/subtract generates a call to Combine/Remove, which returns System.Delegate, // not the operand delegate CType. We must cast to the delegate CType. @@ -598,7 +584,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics throw Error.InternalCompilerError(); } Expr op = Visit(arg); - Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.UserDefinedCallMethod); + Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod); if (expr.Kind == ExpressionKind.Inc || expr.Kind == ExpressionKind.Dec || expr.Kind == ExpressionKind.DecimalInc || expr.Kind == ExpressionKind.DecimalDec) @@ -642,17 +628,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics p1 = Visit(p1); p2 = Visit(p2); FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2); - Expr lift = GetExprFactory().CreateBoolConstant(false); // We never lift to null in C#. - Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.UserDefinedCallMethod); + Expr lift = ExprFactory.CreateBoolConstant(false); // We never lift to null in C#. + Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod); return GenerateCall(pdm, p1, p2, lift, methodInfo); } - private Expr GenerateConversion(Expr arg, CType CType, bool bChecked) - { - return GenerateConversionWithSource(Visit(arg), CType, bChecked || arg.isChecked()); - } + private Expr GenerateConversion(Expr arg, CType CType, bool bChecked) => + GenerateConversionWithSource(Visit(arg), CType, bChecked || arg.isChecked()); - private Expr GenerateConversionWithSource(Expr pTarget, CType pType, bool bChecked) + private static Expr GenerateConversionWithSource(Expr pTarget, CType pType, bool bChecked) { PREDEFMETH pdm = bChecked ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT; Expr pTypeOf = CreateTypeOf(pType); @@ -673,7 +657,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GenerateUserDefinedConversion(arg, type, target, method); } - private Expr GenerateUserDefinedConversion(Expr arg, CType CType, Expr target, MethWithInst method) + private static Expr GenerateUserDefinedConversion(Expr arg, CType CType, Expr target, MethWithInst method) { // The user-defined explicit conversion from enum? to decimal or decimal? requires // that we convert the enum? to its nullable underlying CType. @@ -686,7 +670,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // converting an enum to its underlying CType never fails, so no need to check it. CType underlyingType = arg.Type.StripNubs().UnderlyingEnumType; - CType nullableType = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType); + CType nullableType = TypeManager.GetNullable(underlyingType); Expr typeofNubEnum = CreateTypeOf(nullableType); target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum); } @@ -696,12 +680,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S)) - CType pMethodReturnType = GetSymbolLoader().GetTypeManager().SubstType(method.Meth().RetType, + CType pMethodReturnType = TypeManager.SubstType(method.Meth().RetType, method.GetType(), method.TypeArgs); bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.Type) && IsNullableValueType(CType))); Expr typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType); - Expr methodInfo = GetExprFactory().CreateMethodInfo(method); + Expr methodInfo = ExprFactory.CreateMethodInfo(method); PREDEFMETH pdmInner = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED; Expr callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo); @@ -763,25 +747,19 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GenerateUserDefinedConversion(pCastArgument, pExpr.Type, pConversionSource, pExpr.UserDefinedCallMethod); } - private Expr GenerateParameter(string name, CType CType) + private static Expr GenerateParameter(string name, CType CType) { - GetSymbolLoader().GetPredefindType(PredefinedType.PT_STRING); // force an ensure state - ExprConstant nameString = GetExprFactory().CreateStringConstant(name); + SymbolLoader.GetPredefindType(PredefinedType.PT_STRING); // force an ensure state + ExprConstant nameString = ExprFactory.CreateStringConstant(name); ExprTypeOf pTypeOf = CreateTypeOf(CType); return GenerateCall(PREDEFMETH.PM_EXPRESSION_PARAMETER, pTypeOf, nameString); } - private MethodSymbol GetPreDefMethod(PREDEFMETH pdm) - { - return GetSymbolLoader().getPredefinedMembers().GetMethod(pdm); - } + private static MethodSymbol GetPreDefMethod(PREDEFMETH pdm) => PredefinedMembers.GetMethod(pdm); - private ExprTypeOf CreateTypeOf(CType CType) - { - return GetExprFactory().CreateTypeOf(CType); - } + private static ExprTypeOf CreateTypeOf(CType type) => ExprFactory.CreateTypeOf(type); - private Expr CreateWraps(ExprBoundLambda anonmeth) + private static Expr CreateWraps(ExprBoundLambda anonmeth) { Expr sequence = null; for (Symbol sym = anonmeth.ArgumentScope.firstChild; sym != null; sym = sym.nextChild) @@ -793,15 +771,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Debug.Assert(anonmeth.Expression != null); Expr create = GenerateParameter(local.name.Text, local.GetType()); - local.wrap = GetExprFactory().CreateWrap(create); - Expr save = GetExprFactory().CreateSave(local.wrap); + local.wrap = ExprFactory.CreateWrap(create); + Expr save = ExprFactory.CreateSave(local.wrap); if (sequence == null) { sequence = save; } else { - sequence = GetExprFactory().CreateSequence(sequence, save); + sequence = ExprFactory.CreateSequence(sequence, save); } } @@ -812,7 +790,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { Debug.Assert(expr != null); Debug.Assert(expr.MethWithInst.Meth().IsConstructor()); - Expr constructorInfo = GetExprFactory().CreateMethodInfo(expr.MethWithInst); + Expr constructorInfo = ExprFactory.CreateMethodInfo(expr.MethWithInst); Expr args = GenerateArgsList(expr.OptionalArguments); Expr Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); return GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW, constructorInfo, Params); @@ -825,14 +803,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics for (ExpressionIterator it = new ExpressionIterator(oldArgs); !it.AtEnd(); it.MoveNext()) { Expr oldArg = it.Current(); - GetExprFactory().AppendItemToList(Visit(oldArg), ref newArgs, ref newArgsTail); + ExprFactory.AppendItemToList(Visit(oldArg), ref newArgs, ref newArgsTail); } return newArgs; } private Expr GenerateIndexList(Expr oldIndices) { - CType intType = symbolLoader.GetPredefindType(PredefinedType.PT_INT); + CType intType = SymbolLoader.GetPredefindType(PredefinedType.PT_INT); Expr newIndices = null; Expr newIndicesTail = newIndices; @@ -841,20 +819,20 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics Expr newIndex = it.Current(); if (newIndex.Type != intType) { - newIndex = expressionFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, intType, newIndex); + newIndex = ExprFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, intType, newIndex); newIndex.Flags |= EXPRFLAG.EXF_CHECKOVERFLOW; } Expr rewrittenIndex = Visit(newIndex); - expressionFactory.AppendItemToList(rewrittenIndex, ref newIndices, ref newIndicesTail); + ExprFactory.AppendItemToList(rewrittenIndex, ref newIndices, ref newIndicesTail); } return newIndices; } - private Expr GenerateConstant(Expr expr) + private static Expr GenerateConstant(Expr expr) { EXPRFLAG flags = 0; - AggregateType pObject = GetSymbolLoader().GetPredefindType(PredefinedType.PT_OBJECT); + AggregateType pObject = SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT); if (expr.Type is NullType) { @@ -862,85 +840,85 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE, expr, pTypeOf); } - AggregateType stringType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_STRING); + AggregateType stringType = SymbolLoader.GetPredefindType(PredefinedType.PT_STRING); if (expr.Type != stringType) { flags = EXPRFLAG.EXF_BOX; } - ExprCast cast = GetExprFactory().CreateCast(flags, pObject, expr); + ExprCast cast = ExprFactory.CreateCast(flags, pObject, expr); ExprTypeOf pTypeOf2 = CreateTypeOf(expr.Type); return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE, cast, pTypeOf2); } - private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1) + private static ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1) { MethodSymbol method = GetPreDefMethod(pdm); // this should be enforced in an earlier pass and the transform pass should not // be handling this error if (method == null) return null; - AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); + AggregateType expressionType = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION); MethWithInst mwi = new MethWithInst(method, expressionType); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall call = ExprFactory.CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; } - private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2) + private static ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2) { MethodSymbol method = GetPreDefMethod(pdm); if (method == null) return null; - AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); - Expr args = GetExprFactory().CreateList(arg1, arg2); + AggregateType expressionType = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION); + Expr args = ExprFactory.CreateList(arg1, arg2); MethWithInst mwi = new MethWithInst(method, expressionType); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall call = ExprFactory.CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; } - private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3) + private static ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3) { MethodSymbol method = GetPreDefMethod(pdm); if (method == null) return null; - AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); - Expr args = GetExprFactory().CreateList(arg1, arg2, arg3); + AggregateType expressionType = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION); + Expr args = ExprFactory.CreateList(arg1, arg2, arg3); MethWithInst mwi = new MethWithInst(method, expressionType); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall call = ExprFactory.CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; } - private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3, Expr arg4) + private static ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3, Expr arg4) { MethodSymbol method = GetPreDefMethod(pdm); if (method == null) return null; - AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); - Expr args = GetExprFactory().CreateList(arg1, arg2, arg3, arg4); + AggregateType expressionType = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION); + Expr args = ExprFactory.CreateList(arg1, arg2, arg3, arg4); MethWithInst mwi = new MethWithInst(method, expressionType); - ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); - ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); + ExprMemberGroup pMemGroup = ExprFactory.CreateMemGroup(null, mwi); + ExprCall call = ExprFactory.CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; } - private ExprArrayInit GenerateParamsArray(Expr args, PredefinedType pt) + private static ExprArrayInit GenerateParamsArray(Expr args, PredefinedType pt) { int parameterCount = ExpressionIterator.Count(args); - AggregateType paramsArrayElementType = GetSymbolLoader().GetPredefindType(pt); - ArrayType paramsArrayType = GetSymbolLoader().GetTypeManager().GetArray(paramsArrayElementType, 1, true); - ExprConstant paramsArrayArg = GetExprFactory().CreateIntegerConstant(parameterCount); - return GetExprFactory().CreateArrayInit(paramsArrayType, args, paramsArrayArg, new int[] { parameterCount }, parameterCount); + AggregateType paramsArrayElementType = SymbolLoader.GetPredefindType(pt); + ArrayType paramsArrayType = TypeManager.GetArray(paramsArrayElementType, 1, true); + ExprConstant paramsArrayArg = ExprFactory.CreateIntegerConstant(parameterCount); + return ExprFactory.CreateArrayInit(paramsArrayType, args, paramsArrayArg, new int[] { parameterCount }, parameterCount); } - private void FixLiftedUserDefinedBinaryOperators(ExprBinOp expr, ref Expr pp1, ref Expr pp2) + private static void FixLiftedUserDefinedBinaryOperators(ExprBinOp expr, ref Expr pp1, ref Expr pp2) { // If we have lifted T1 op T2 to T1? op T2?, and we have an expression T1 op T2? or T1? op T2 then // we need to ensure that the unlifted actual arguments are promoted to their nullable CType. @@ -968,8 +946,8 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return; } - CType nubfptype1 = GetSymbolLoader().GetTypeManager().GetNullable(fptype1); - CType nubfptype2 = GetSymbolLoader().GetTypeManager().GetNullable(fptype2); + CType nubfptype1 = TypeManager.GetNullable(fptype1); + CType nubfptype2 = TypeManager.GetNullable(fptype2); // If we have null op X, or T1 op T2?, or T1 op null, lift first arg to T1? if (aatype1 is NullType || aatype1 == fptype1 && (aatype2 == nubfptype2 || aatype2 is NullType)) { @@ -985,10 +963,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics pp2 = new2; } - private bool IsNullableValueType(CType pType) => + private static bool IsNullableValueType(CType pType) => pType is NullableType && pType.StripNubs() is AggregateType agg && agg.OwningAggregate.IsValueType(); - private bool IsNullableValueAccess(Expr pExpr, Expr pObject) + private static bool IsNullableValueAccess(Expr pExpr, Expr pObject) { Debug.Assert(pExpr != null); return pExpr is ExprProperty prop && prop.MemberGroup.OptionalObject == pObject && pObject.Type is NullableType; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ZeroInitialize.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ZeroInitialize.cs index 66051b6..4bff9bd 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ZeroInitialize.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ZeroInitialize.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; + namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal sealed class ExprZeroInit : ExprWithType @@ -10,5 +12,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics : base(ExpressionKind.ZeroInit, type) { } + + public override object Object => Activator.CreateInstance(Type.AssociatedSystemType); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/TypeBind.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/TypeBind.cs index 193bbb4..3f21c17 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/TypeBind.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/TypeBind.cs @@ -32,7 +32,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal static class TypeBind { // Check the constraints of any type arguments in the given Type. - public static bool CheckConstraints(CSemanticChecker checker, ErrorHandling errHandling, CType type, CheckConstraintsFlags flags) + public static bool CheckConstraints(CType type, CheckConstraintsFlags flags) { type = type.GetNakedType(false); @@ -81,7 +81,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // outer type has already been checked then don't bother checking it. if (ats.OuterType != null && ((flags & CheckConstraintsFlags.Outer) != 0 || !ats.OuterType.ConstraintError.HasValue)) { - if (!CheckConstraints(checker, errHandling, ats.OuterType, flags)) + if (!CheckConstraints(ats.OuterType, flags)) { ats.ConstraintError = true; return false; @@ -90,7 +90,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (typeVars.Count > 0) { - if (!CheckConstraintsCore(checker, errHandling, ats.OwningAggregate, typeVars, typeArgsThis, typeArgsAll, null, flags & CheckConstraintsFlags.NoErrors)) + if (!CheckConstraintsCore(ats.OwningAggregate, typeVars, typeArgsThis, typeArgsAll, null, flags & CheckConstraintsFlags.NoErrors)) { ats.ConstraintError = true; return false; @@ -103,7 +103,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics CType arg = typeArgsThis[i].GetNakedType(true); if (arg is AggregateType atArg && !atArg.ConstraintError.HasValue) { - CheckConstraints(checker, errHandling, atArg, flags | CheckConstraintsFlags.Outer); + CheckConstraints(atArg, flags | CheckConstraintsFlags.Outer); if (atArg.ConstraintError.GetValueOrDefault()) { ats.ConstraintError = true; @@ -118,7 +118,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics //////////////////////////////////////////////////////////////////////////////// // Check the constraints on the method instantiation. - public static void CheckMethConstraints(CSemanticChecker checker, ErrorHandling errCtx, MethWithInst mwi) + public static void CheckMethConstraints(MethWithInst mwi) { Debug.Assert(mwi.Meth() != null && mwi.GetType() != null && mwi.TypeArgs != null); Debug.Assert(mwi.Meth().typeVars.Count == mwi.TypeArgs.Count); @@ -126,15 +126,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (mwi.TypeArgs.Count > 0) { - CheckConstraintsCore(checker, errCtx, mwi.Meth(), mwi.Meth().typeVars, mwi.TypeArgs, mwi.GetType().TypeArgsAll, mwi.TypeArgs, CheckConstraintsFlags.None); + CheckConstraintsCore(mwi.Meth(), mwi.Meth().typeVars, mwi.TypeArgs, mwi.GetType().TypeArgsAll, mwi.TypeArgs, CheckConstraintsFlags.None); } } + //////////////////////////////////////////////////////////////////////////////// // Check whether typeArgs satisfies the constraints of typeVars. The // typeArgsCls and typeArgsMeth are used for substitution on the bounds. The // tree and symErr are used for error reporting. - - private static bool CheckConstraintsCore(CSemanticChecker checker, ErrorHandling errHandling, Symbol symErr, TypeArray typeVars, TypeArray typeArgs, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags) + private static bool CheckConstraintsCore(Symbol symErr, TypeArray typeVars, TypeArray typeArgs, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags) { Debug.Assert(typeVars.Count == typeArgs.Count); Debug.Assert(typeVars.Count > 0); @@ -146,7 +146,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics TypeParameterType var = (TypeParameterType)typeVars[i]; CType arg = typeArgs[i]; - if (!CheckSingleConstraint(checker, errHandling, symErr, var, arg, typeArgsCls, typeArgsMeth, flags)) + if (!CheckSingleConstraint(symErr, var, arg, typeArgsCls, typeArgsMeth, flags)) { return false; } @@ -155,7 +155,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - private static bool CheckSingleConstraint(CSemanticChecker checker, ErrorHandling errHandling, Symbol symErr, TypeParameterType var, CType arg, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags) + private static bool CheckSingleConstraint(Symbol symErr, TypeParameterType var, CType arg, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags) { Debug.Assert(!(arg is PointerType)); Debug.Assert(!arg.IsStaticClass); @@ -166,13 +166,13 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (fReportErrors) { - throw errHandling.Error(ErrorCode.ERR_RefConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); + throw ErrorHandling.Error(ErrorCode.ERR_RefConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); } return false; } - TypeArray bnds = checker.SymbolLoader.GetTypeManager().SubstTypeArray(var.Bounds, typeArgsCls, typeArgsMeth); + TypeArray bnds = TypeManager.SubstTypeArray(var.Bounds, typeArgsCls, typeArgsMeth); int itypeMin = 0; if (var.HasValConstraint) @@ -189,7 +189,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { if (fReportErrors) { - throw errHandling.Error(ErrorCode.ERR_ValConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); + throw ErrorHandling.Error(ErrorCode.ERR_ValConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); } return false; @@ -205,7 +205,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics for (int j = itypeMin; j < bnds.Count; j++) { CType typeBnd = bnds[j]; - if (!SatisfiesBound(checker, arg, typeBnd)) + if (!SatisfiesBound(arg, typeBnd)) { if (fReportErrors) { @@ -226,7 +226,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // to which they have an implicit reference conversion error = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType; } - else if (arg is NullableType nubArg && checker.SymbolLoader.HasBaseConversion(nubArg.UnderlyingType, typeBnd)) // This is inlining FBoxingConv + else if (arg is NullableType nubArg && SymbolLoader.HasBaseConversion(nubArg.UnderlyingType, typeBnd)) // This is inlining FBoxingConv { // nullable types do not satisfy bounds to every type that they are boxable to // They only satisfy bounds of object and ValueType @@ -257,7 +257,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics error = ErrorCode.ERR_GenericConstraintNotSatisfiedValType; } - throw errHandling.Error(error, new ErrArg(symErr), new ErrArg(typeBnd, ErrArgFlags.Unique), var, new ErrArg(arg, ErrArgFlags.Unique)); + throw ErrorHandling.Error(error, new ErrArg(symErr), new ErrArg(typeBnd, ErrArgFlags.Unique), var, new ErrArg(arg, ErrArgFlags.Unique)); } return false; @@ -278,7 +278,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // have all the information necessary yet, if it is not fully bound. // by calling LookupAggMember, it will ensure that we will update all the // information necessary at least for the given method. - checker.SymbolLoader.LookupAggMember(NameManager.GetPredefinedName(PredefinedName.PN_CTOR), agg, symbmask_t.MASK_ALL); + SymbolLoader.LookupAggMember(NameManager.GetPredefinedName(PredefinedName.PN_CTOR), agg, symbmask_t.MASK_ALL); if (agg.HasPubNoArgCtor() && !agg.IsAbstract()) { @@ -288,7 +288,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (fReportErrors) { - throw errHandling.Error(ErrorCode.ERR_NewConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); + throw ErrorHandling.Error(ErrorCode.ERR_NewConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg); } return false; @@ -299,7 +299,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // typeBnd could be just about any type (since we added naked type parameter // constraints). - private static bool SatisfiesBound(CSemanticChecker checker, CType arg, CType typeBnd) + private static bool SatisfiesBound(CType arg, CType typeBnd) { if (typeBnd == arg) return true; @@ -341,7 +341,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics case TypeKind.TK_TypeParameterType: case TypeKind.TK_ArrayType: case TypeKind.TK_AggregateType: - return checker.SymbolLoader.HasBaseConversion(arg, typeBnd); + return SymbolLoader.HasBaseConversion(arg, typeBnd); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/AggregateType.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/AggregateType.cs index 3bc9bc9..6934cae 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/AggregateType.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/AggregateType.cs @@ -60,8 +60,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Ensure that invariant here. Debug.Assert(outerType == null || outerType.TypeArgsAll != null); - TypeArgsAll = parent.GetTypeManager() - .ConcatenateTypeArrays(outerType != null ? outerType.TypeArgsAll : BSYMMGR.EmptyTypeArray(), typeArgsThis); + TypeArgsAll = outerType != null ? TypeArray.Concat(outerType.TypeArgsAll, typeArgsThis) : typeArgsThis; } public bool? ConstraintError; // Did the constraints check produce an error? @@ -101,10 +100,9 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // If we don't have a generic type definition, then we just need to set our base // class. This is so that if we have a base type that's generic, we'll be // getting the correctly instantiated base type. - TypeManager manager = OwningAggregate.GetTypeManager(); - AggregateType baseClass = manager.SymbolTable.GetCTypeFromType(baseSysType) as AggregateType; + AggregateType baseClass = SymbolTable.GetCTypeFromType(baseSysType) as AggregateType; Debug.Assert(baseClass != null); - _baseType = manager.SubstType(baseClass, TypeArgsAll); + _baseType = TypeManager.SubstType(baseClass, TypeArgsAll); } return _baseType; @@ -123,7 +121,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics yield return iface; } - yield return OwningAggregate.GetTypeManager().ObjectAggregateType; + yield return PredefinedTypes.GetPredefinedAggregate(PredefinedType.PT_OBJECT).getThisType(); } else { @@ -139,7 +137,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public TypeArray TypeArgsAll { get; } - public TypeArray IfacesAll => _ifacesAll ?? (_ifacesAll = OwningAggregate.GetTypeManager().SubstTypeArray(OwningAggregate.GetIfacesAll(), TypeArgsAll)); + public TypeArray IfacesAll => _ifacesAll ?? (_ifacesAll = TypeManager.SubstTypeArray(OwningAggregate.GetIfacesAll(), TypeArgsAll)); private bool IsCollectionType { @@ -166,24 +164,27 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - public TypeArray GetWinRTCollectionIfacesAll(SymbolLoader pSymbolLoader) + public TypeArray WinRTCollectionIfacesAll { - if (_winrtifacesAll == null) + get { - List typeList = new List(); - foreach (AggregateType type in IfacesAll.Items) + if (_winrtifacesAll == null) { - Debug.Assert(type.IsInterfaceType); - if (type.IsCollectionType) + List typeList = new List(); + foreach (AggregateType type in IfacesAll.Items) { - typeList.Add(type); + Debug.Assert(type.IsInterfaceType); + if (type.IsCollectionType) + { + typeList.Add(type); + } } + + _winrtifacesAll = TypeArray.Allocate(typeList.ToArray()); } - _winrtifacesAll = pSymbolLoader.getBSymmgr().AllocParams(typeList.Count, typeList.ToArray()); + return _winrtifacesAll; } - - return _winrtifacesAll; } public override bool IsReferenceType => OwningAggregate.IsRefType(); @@ -384,5 +385,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } } + + public override AggregateType GetAts() => this; } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/ArrayType.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/ArrayType.cs index 4819379..75ba3ac 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/ArrayType.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/ArrayType.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { @@ -59,5 +60,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public override FUNDTYPE FundamentalType => FUNDTYPE.FT_REF; public override ConstValKind ConstValKind => ConstValKind.IntPtr; + + public override AggregateType GetAts() => SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY); } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/NullableType.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/NullableType.cs index 8c56e47..d0fab06 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/NullableType.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/NullableType.cs @@ -19,19 +19,15 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal sealed class NullableType : CType { private AggregateType _ats; - private readonly BSYMMGR _symmgr; - private readonly TypeManager _typeManager; - public NullableType(CType underlyingType, BSYMMGR symmgr, TypeManager typeManager) + public NullableType(CType underlyingType) : base(TypeKind.TK_NullableType) { UnderlyingType = underlyingType; - _symmgr = symmgr; - _typeManager = typeManager; } - public AggregateType GetAts() => _ats ?? (_ats = _typeManager.GetAggregate( - _typeManager.GetNullable(), _symmgr.AllocParams(UnderlyingType))); + public override AggregateType GetAts() => + _ats ?? (_ats = TypeManager.GetAggregate(TypeManager.GetNullable(), TypeArray.Allocate(UnderlyingType))); public override CType StripNubs() => UnderlyingType; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/PredefinedTypes.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/PredefinedTypes.cs index d5e5d9f..7a80b8f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/PredefinedTypes.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/PredefinedTypes.cs @@ -9,22 +9,14 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class PredefinedTypes + internal static class PredefinedTypes { - private SymbolTable _runtimeBinderSymbolTable; - private readonly BSYMMGR _symbolManager; - private AggregateSymbol[] _predefSyms; // array of predefined symbol types. - - public PredefinedTypes(BSYMMGR symbolManager) - { - _symbolManager = symbolManager; - _runtimeBinderSymbolTable = null; - } + private static readonly AggregateSymbol[] s_predefSymbols = new AggregateSymbol[(int)PredefinedType.PT_COUNT]; // We want to delay load the predefined symbols as needed. - private AggregateSymbol DelayLoadPredefSym(PredefinedType pt) + private static AggregateSymbol DelayLoadPredefSym(PredefinedType pt) { - AggregateType type = (AggregateType)_runtimeBinderSymbolTable.GetCTypeFromType(PredefinedTypeFacts.GetAssociatedSystemType(pt)); + AggregateType type = (AggregateType)SymbolTable.GetCTypeFromType(PredefinedTypeFacts.GetAssociatedSystemType(pt)); AggregateSymbol sym = type.OwningAggregate; return InitializePredefinedType(sym, pt); } @@ -38,21 +30,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return sym; } - public void Init(SymbolTable symtable) - { - _runtimeBinderSymbolTable = symtable; - Debug.Assert(_symbolManager != null); - Debug.Assert(_predefSyms == null); - - _predefSyms = new AggregateSymbol[(int)PredefinedType.PT_COUNT]; - } - - public AggregateSymbol GetPredefinedAggregate(PredefinedType pt) => - _predefSyms[(int)pt] ?? (_predefSyms[(int)pt] = DelayLoadPredefSym(pt)); + public static AggregateSymbol GetPredefinedAggregate(PredefinedType pt) => + s_predefSymbols[(int)pt] ?? (s_predefSymbols[(int)pt] = DelayLoadPredefSym(pt)); //////////////////////////////////////////////////////////////////////////////// // Some of the predefined types have built-in names, like "int" or "string" or - // "object". This return the nice name if one exists; otherwise null is + // "object". This return the nice name if one exists; otherwise null is // returned. private static string GetNiceName(PredefinedType pt) => PredefinedTypeFacts.GetNiceName(pt); @@ -63,8 +46,6 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal static class PredefinedTypeFacts { - internal static string GetName(PredefinedType type) => s_types[(int)type].Name; - internal static FUNDTYPE GetFundType(PredefinedType type) => s_types[(int)type].FundType; internal static Type GetAssociatedSystemType(PredefinedType type) => s_types[(int)type].AssociatedSystemType; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/Type.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/Type.cs index 3f13a9b..d8a7386 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/Type.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/Type.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using Microsoft.CSharp.RuntimeBinder.Syntax; @@ -122,5 +123,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics public virtual bool IsNonNullableValueType => false; public virtual bool IsReferenceType => false; + + [ExcludeFromCodeCoverage] // Should only be called through override. + public virtual AggregateType GetAts() + { + Debug.Fail("Bad type for AsAggregateType"); + return null; + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeArray.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeArray.cs index 414a895..1f2cd08 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeArray.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeArray.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Microsoft.CSharp.RuntimeBinder.Semantics @@ -13,7 +15,76 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics internal sealed class TypeArray { - public TypeArray(CType[] types) + //////////////////////////////////////////////////////////////////////////////// + // Allocate a type array; used to represent a parameter list. + // We use a hash table to make sure that allocating the same type array twice + // returns the same value. This does two things: + // + // 1) Save a lot of memory. + // 2) Make it so parameter lists can be compared by a simple pointer comparison + + private readonly struct TypeArrayKey : IEquatable + { + private readonly CType[] _types; + private readonly int _hashCode; + + public TypeArrayKey(CType[] types) + { + _types = types; + int hashCode = 0x162A16FE; + foreach (CType type in types) + { + hashCode = (hashCode << 5) - hashCode; + if (type != null) + { + hashCode ^= type.GetHashCode(); + } + } + + _hashCode = hashCode; + } + + public bool Equals(TypeArrayKey other) + { + CType[] types = _types; + CType[] otherTypes = other._types; + if (otherTypes == types) + { + return true; + } + + if (other._hashCode != _hashCode || otherTypes.Length != types.Length) + { + return false; + } + + for (int i = 0; i < types.Length; i++) + { + if (types[i] != otherTypes[i]) + { + return false; + } + } + + return true; + } + + [ExcludeFromCodeCoverage] // Typed overload should always be the method called. + public override bool Equals(object obj) + { + Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); + return obj is TypeArrayKey key && Equals(key); + } + + public override int GetHashCode() => _hashCode; + } + + private static readonly Dictionary s_tableTypeArrays = + new Dictionary(); + + public static readonly TypeArray Empty = new TypeArray(Array.Empty()); + + private TypeArray(CType[] types) { Debug.Assert(types != null); Items = types; @@ -33,5 +104,60 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } public void CopyItems(int i, int c, CType[] dest) => Array.Copy(Items, i, dest, 0, c); + + public static TypeArray Allocate(int ctype, TypeArray array, int offset) + { + if (ctype == 0) + { + return Empty; + } + + if (ctype == array.Count) + { + return array; + } + + CType[] types = array.Items; + CType[] newTypes = new CType[ctype]; + Array.ConstrainedCopy(types, offset, newTypes, 0, ctype); + return Allocate(newTypes); + } + + public static TypeArray Allocate(params CType[] types) + { + if (types?.Length > 0) + { + TypeArrayKey key = new TypeArrayKey(types); + if (!s_tableTypeArrays.TryGetValue(key, out TypeArray result)) + { + result = new TypeArray(types); + s_tableTypeArrays.Add(key, result); + } + + return result; + } + + return Empty; + } + + public static TypeArray Concat(TypeArray pta1, TypeArray pta2) + { + CType[] prgtype1 = pta1.Items; + if (prgtype1.Length == 0) + { + return pta2; + } + + CType[] prgtype2 = pta2.Items; + if (prgtype2.Length == 0) + { + return pta1; + } + + CType[] combined = new CType[prgtype1.Length + prgtype2.Length]; + Array.Copy(prgtype1, 0, combined, 0, prgtype1.Length); + Array.Copy(prgtype2, 0, combined, prgtype1.Length, prgtype2.Length); + return Allocate(combined); + } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeManager.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeManager.cs index 90f48fc..60ab7af 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeManager.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeManager.cs @@ -8,35 +8,17 @@ using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Security; using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed class TypeManager + internal static class TypeManager { - private BSYMMGR _BSymmgr; - private PredefinedTypes _predefTypes; + private static readonly Dictionary<(Assembly, Assembly), bool> s_internalsVisibleToCache = + new Dictionary<(Assembly, Assembly), bool>(); - private readonly TypeTable _typeTable; - private SymbolTable _symbolTable; - - private readonly StdTypeVarColl _stvcMethod; - - public TypeManager(BSYMMGR bsymmgr, PredefinedTypes predefTypes) - { - _typeTable = new TypeTable(); - - _stvcMethod = new StdTypeVarColl(); - _BSymmgr = bsymmgr; - _predefTypes = predefTypes; - } - - public void InitTypeFactory(SymbolTable table) - { - _symbolTable = table; - } - - public SymbolTable SymbolTable => _symbolTable; + private static readonly StdTypeVarColl s_stvcMethod = new StdTypeVarColl(); private sealed class StdTypeVarColl { @@ -58,31 +40,31 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // comparison when binding. The standard method type variables are useful during // binding for signature comparison. - public TypeParameterType GetTypeVarSym(int iv, TypeManager pTypeManager, bool fMeth) + public TypeParameterType GetTypeVarSym(int iv, bool fMeth) { Debug.Assert(iv >= 0); TypeParameterType tpt; - if (iv >= this.prgptvs.Count) + if (iv >= prgptvs.Count) { TypeParameterSymbol pTypeParameter = new TypeParameterSymbol(); pTypeParameter.SetIsMethodTypeParameter(fMeth); pTypeParameter.SetIndexInOwnParameters(iv); pTypeParameter.SetIndexInTotalParameters(iv); pTypeParameter.SetAccess(ACCESS.ACC_PRIVATE); - tpt = pTypeManager.GetTypeParameter(pTypeParameter); - this.prgptvs.Add(tpt); + tpt = GetTypeParameter(pTypeParameter); + prgptvs.Add(tpt); } else { - tpt = this.prgptvs[iv]; + tpt = prgptvs[iv]; } Debug.Assert(tpt != null); return tpt; } } - public ArrayType GetArray(CType elementType, int args, bool isSZArray) + public static ArrayType GetArray(CType elementType, int args, bool isSZArray) { Debug.Assert(args > 0 && args < 32767); Debug.Assert(args == 1 || !isSZArray); @@ -90,12 +72,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics int rankNum = isSZArray ? 0 : args; // See if we already have an array type of this element type and rank. - ArrayType pArray = _typeTable.LookupArray(elementType, rankNum); + ArrayType pArray = TypeTable.LookupArray(elementType, rankNum); if (pArray == null) { // No existing array symbol. Create a new one. pArray = new ArrayType(elementType, args, isSZArray); - _typeTable.InsertArray(elementType, rankNum, pArray); + TypeTable.InsertArray(elementType, rankNum, pArray); } Debug.Assert(pArray.Rank == args); @@ -104,25 +86,24 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pArray; } - public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs) + public static AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs) { - Debug.Assert(agg.GetTypeManager() == this); Debug.Assert(atsOuter == null || atsOuter.OwningAggregate == agg.Parent, ""); if (typeArgs == null) { - typeArgs = BSYMMGR.EmptyTypeArray(); + typeArgs = TypeArray.Empty; } Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count); - AggregateType pAggregate = _typeTable.LookupAggregate(agg, atsOuter, typeArgs); + AggregateType pAggregate = TypeTable.LookupAggregate(agg, atsOuter, typeArgs); if (pAggregate == null) { pAggregate = new AggregateType(agg, typeArgs, atsOuter); Debug.Assert(!pAggregate.ConstraintError.HasValue); - _typeTable.InsertAggregate(agg, atsOuter, typeArgs, pAggregate); + TypeTable.InsertAggregate(agg, atsOuter, typeArgs, pAggregate); } Debug.Assert(pAggregate.OwningAggregate == agg); @@ -132,7 +113,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pAggregate; } - public AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll) + public static AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll) { Debug.Assert(typeArgsAll != null && typeArgsAll.Count == agg.GetTypeVarsAll().Count); @@ -147,21 +128,21 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics int cvarOuter = aggOuter.GetTypeVarsAll().Count; Debug.Assert(cvarOuter <= typeArgsAll.Count); - TypeArray typeArgsOuter = _BSymmgr.AllocParams(cvarOuter, typeArgsAll, 0); - TypeArray typeArgsInner = _BSymmgr.AllocParams(agg.GetTypeVars().Count, typeArgsAll, cvarOuter); + TypeArray typeArgsOuter = TypeArray.Allocate(cvarOuter, typeArgsAll, 0); + TypeArray typeArgsInner = TypeArray.Allocate(agg.GetTypeVars().Count, typeArgsAll, cvarOuter); AggregateType atsOuter = GetAggregate(aggOuter, typeArgsOuter); return GetAggregate(agg, atsOuter, typeArgsInner); } - public PointerType GetPointer(CType baseType) + public static PointerType GetPointer(CType baseType) { - PointerType pPointer = _typeTable.LookupPointer(baseType); + PointerType pPointer = TypeTable.LookupPointer(baseType); if (pPointer == null) { // No existing type. Create a new one. pPointer = new PointerType(baseType); - _typeTable.InsertPointer(baseType, pPointer); + TypeTable.InsertPointer(baseType, pPointer); } Debug.Assert(pPointer.ReferentType == baseType); @@ -169,28 +150,28 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pPointer; } - public NullableType GetNullable(CType pUnderlyingType) + public static NullableType GetNullable(CType pUnderlyingType) { Debug.Assert(!(pUnderlyingType is NullableType), "Attempt to make nullable of nullable"); - NullableType pNullableType = _typeTable.LookupNullable(pUnderlyingType); + NullableType pNullableType = TypeTable.LookupNullable(pUnderlyingType); if (pNullableType == null) { - pNullableType = new NullableType(pUnderlyingType, _BSymmgr, this); - _typeTable.InsertNullable(pUnderlyingType, pNullableType); + pNullableType = new NullableType(pUnderlyingType); + TypeTable.InsertNullable(pUnderlyingType, pNullableType); } return pNullableType; } - public ParameterModifierType GetParameterModifier(CType paramType, bool isOut) + public static ParameterModifierType GetParameterModifier(CType paramType, bool isOut) { - ParameterModifierType pParamModifier = _typeTable.LookupParameterModifier(paramType, isOut); + ParameterModifierType pParamModifier = TypeTable.LookupParameterModifier(paramType, isOut); if (pParamModifier == null) { // No existing parammod symbol. Create a new one. pParamModifier = new ParameterModifierType(paramType, isOut); - _typeTable.InsertParameterModifier(paramType, isOut, pParamModifier); + TypeTable.InsertParameterModifier(paramType, isOut, pParamModifier); } Debug.Assert(pParamModifier.ParameterType == paramType); @@ -198,16 +179,16 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return pParamModifier; } - public AggregateSymbol GetNullable() => GetPredefAgg(PredefinedType.PT_G_OPTIONAL); + public static AggregateSymbol GetNullable() => GetPredefAgg(PredefinedType.PT_G_OPTIONAL); - private CType SubstType(CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth, bool denormMeth) + private static CType SubstType(CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth, bool denormMeth) { Debug.Assert(typeSrc != null); SubstContext ctx = new SubstContext(typeArgsCls, typeArgsMeth, denormMeth); return ctx.IsNop ? typeSrc : SubstTypeCore(typeSrc, ctx); } - public AggregateType SubstType(AggregateType typeSrc, TypeArray typeArgsCls) + public static AggregateType SubstType(AggregateType typeSrc, TypeArray typeArgsCls) { Debug.Assert(typeSrc != null); @@ -215,10 +196,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return ctx.IsNop ? typeSrc : SubstTypeCore(typeSrc, ctx); } - private CType SubstType(CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) => + private static CType SubstType(CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) => SubstType(typeSrc, typeArgsCls, typeArgsMeth, false); - public TypeArray SubstTypeArray(TypeArray taSrc, SubstContext ctx) + public static TypeArray SubstTypeArray(TypeArray taSrc, SubstContext ctx) { if (taSrc != null && taSrc.Count != 0 && ctx != null && !ctx.IsNop) { @@ -237,7 +218,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics dsts[i] = SubstTypeCore(srcs[i], ctx); } - return _BSymmgr.AllocParams(dsts); + return TypeArray.Allocate(dsts); } } } @@ -245,14 +226,14 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return taSrc; } - public TypeArray SubstTypeArray(TypeArray taSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) + public static TypeArray SubstTypeArray(TypeArray taSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) => taSrc == null || taSrc.Count == 0 ? taSrc : SubstTypeArray(taSrc, new SubstContext(typeArgsCls, typeArgsMeth, false)); - public TypeArray SubstTypeArray(TypeArray taSrc, TypeArray typeArgsCls) => SubstTypeArray(taSrc, typeArgsCls, null); + public static TypeArray SubstTypeArray(TypeArray taSrc, TypeArray typeArgsCls) => SubstTypeArray(taSrc, typeArgsCls, null); - private AggregateType SubstTypeCore(AggregateType type, SubstContext ctx) + private static AggregateType SubstTypeCore(AggregateType type, SubstContext ctx) { TypeArray args = type.TypeArgsAll; if (args.Count > 0) @@ -267,7 +248,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return type; } - private CType SubstTypeCore(CType type, SubstContext pctx) + private static CType SubstTypeCore(CType type, SubstContext pctx) { CType typeSrc; CType typeDst; @@ -331,7 +312,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - public bool SubstEqualTypes(CType typeDst, CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth, bool denormMeth) + public static bool SubstEqualTypes(CType typeDst, CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth, bool denormMeth) { if (typeDst.Equals(typeSrc)) { @@ -344,7 +325,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return !ctx.IsNop && SubstEqualTypesCore(typeDst, typeSrc, ctx); } - public bool SubstEqualTypeArrays(TypeArray taDst, TypeArray taSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) + public static bool SubstEqualTypeArrays(TypeArray taDst, TypeArray taSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth) { // Handle the simple common cases first. if (taDst == taSrc || (taDst != null && taDst.Equals(taSrc))) @@ -378,7 +359,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return true; } - private bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx) + private static bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx) { LRecurse: // Label used for "tail" recursion. @@ -564,59 +545,36 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics } } - public AggregateSymbol GetPredefAgg(PredefinedType pt) => _predefTypes.GetPredefinedAggregate(pt); - - public TypeArray ConcatenateTypeArrays(TypeArray pTypeArray1, TypeArray pTypeArray2) - { - return _BSymmgr.ConcatParams(pTypeArray1, pTypeArray2); - } + public static AggregateSymbol GetPredefAgg(PredefinedType pt) => PredefinedTypes.GetPredefinedAggregate(pt); - public AggregateType SubstType(AggregateType typeSrc, SubstContext ctx) => + public static AggregateType SubstType(AggregateType typeSrc, SubstContext ctx) => ctx == null || ctx.IsNop ? typeSrc : SubstTypeCore(typeSrc, ctx); - public CType SubstType(CType typeSrc, SubstContext pctx) => + public static CType SubstType(CType typeSrc, SubstContext pctx) => pctx == null || pctx.IsNop ? typeSrc : SubstTypeCore(typeSrc, pctx); - public CType SubstType(CType typeSrc, AggregateType atsCls) - { - return SubstType(typeSrc, atsCls, (TypeArray)null); - } + public static CType SubstType(CType typeSrc, AggregateType atsCls) => SubstType(typeSrc, atsCls, null); - public CType SubstType(CType typeSrc, AggregateType atsCls, TypeArray typeArgsMeth) - { - return SubstType(typeSrc, atsCls?.TypeArgsAll, typeArgsMeth); - } + public static CType SubstType(CType typeSrc, AggregateType atsCls, TypeArray typeArgsMeth) => + SubstType(typeSrc, atsCls?.TypeArgsAll, typeArgsMeth); - public CType SubstType(CType typeSrc, CType typeCls, TypeArray typeArgsMeth) - { - return SubstType(typeSrc, (typeCls as AggregateType)?.TypeArgsAll, typeArgsMeth); - } + public static CType SubstType(CType typeSrc, CType typeCls, TypeArray typeArgsMeth) => + SubstType(typeSrc, (typeCls as AggregateType)?.TypeArgsAll, typeArgsMeth); - public TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls, TypeArray typeArgsMeth) - { - return SubstTypeArray(taSrc, atsCls?.TypeArgsAll, typeArgsMeth); - } + public static TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls, TypeArray typeArgsMeth) => + SubstTypeArray(taSrc, atsCls?.TypeArgsAll, typeArgsMeth); - public TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls) - { - return this.SubstTypeArray(taSrc, atsCls, (TypeArray)null); - } + public static TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls) => SubstTypeArray(taSrc, atsCls, null); - private bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls, TypeArray typeArgsMeth) => + private static bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls, TypeArray typeArgsMeth) => SubstEqualTypes(typeDst, typeSrc, (typeCls as AggregateType)?.TypeArgsAll, typeArgsMeth, false); - public bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls) - { - return SubstEqualTypes(typeDst, typeSrc, typeCls, (TypeArray)null); - } + public static bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls) => SubstEqualTypes(typeDst, typeSrc, typeCls, null); - public TypeParameterType GetStdMethTypeVar(int iv) - { - return _stvcMethod.GetTypeVarSym(iv, this, true); - } + public static TypeParameterType GetStdMethTypeVar(int iv) => s_stvcMethod.GetTypeVarSym(iv, true); // These are singletons for each. - public TypeParameterType GetTypeParameter(TypeParameterSymbol pSymbol) + public static TypeParameterType GetTypeParameter(TypeParameterSymbol pSymbol) { Debug.Assert(pSymbol.GetTypeParameterType() == null); // Should have been checked first before creating return new TypeParameterType(pSymbol); @@ -626,7 +584,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // RUNTIME BINDER ONLY CHANGE // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - internal CType GetBestAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, CType typeSrc) + internal static CType GetBestAccessibleType(AggregateSymbol context, CType typeSrc) { // This method implements the "best accessible type" algorithm for determining the type // of untyped arguments in the runtime binder. It is also used in method type inference @@ -634,13 +592,11 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // The new type is returned in an out parameter. The result will be true (and the out param // non-null) only when the algorithm could find a suitable accessible type. - - Debug.Assert(semanticChecker != null); Debug.Assert(typeSrc != null); Debug.Assert(!(typeSrc is ParameterModifierType)); Debug.Assert(!(typeSrc is PointerType)); - if (semanticChecker.CheckTypeAccess(typeSrc, context)) + if (CSemanticChecker.CheckTypeAccess(typeSrc, context)) { // If we already have an accessible type, then use it. return typeSrc; @@ -653,12 +609,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics { for (;;) { - if ((aggSrc.IsInterfaceType || aggSrc.IsDelegateType) && TryVarianceAdjustmentToGetAccessibleType(semanticChecker, context, aggSrc, out CType typeDst)) + if ((aggSrc.IsInterfaceType || aggSrc.IsDelegateType) && TryVarianceAdjustmentToGetAccessibleType(context, aggSrc, out CType typeDst)) { // If we have an interface or delegate type, then it can potentially be varied by its type arguments // to produce an accessible type, and if that's the case, then return that. // Example: IEnumerable --> IEnumerable - Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); + Debug.Assert(CSemanticChecker.CheckTypeAccess(typeDst, context)); return typeDst; } @@ -672,7 +628,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GetPredefAgg(PredefinedType.PT_OBJECT).getThisType(); } - if (semanticChecker.CheckTypeAccess(baseType, context)) + if (CSemanticChecker.CheckTypeAccess(baseType, context)) { return baseType; } @@ -684,12 +640,12 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics if (typeSrc is ArrayType arrSrc) { - if (TryArrayVarianceAdjustmentToGetAccessibleType(semanticChecker, context, arrSrc, out CType typeDst)) + if (TryArrayVarianceAdjustmentToGetAccessibleType(context, arrSrc, out CType typeDst)) { // Similarly to the interface and delegate case, arrays are covariant in their element type and // so we can potentially produce an array type that is accessible. // Example: PrivateConcreteFoo[] --> PublicAbstractFoo[] - Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); + Debug.Assert(CSemanticChecker.CheckTypeAccess(typeDst, context)); return typeDst; } @@ -704,7 +660,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return GetPredefAgg(PredefinedType.PT_VALUE).getThisType(); } - private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, AggregateType typeSrc, out CType typeDst) + private static bool TryVarianceAdjustmentToGetAccessibleType(AggregateSymbol context, AggregateType typeSrc, out CType typeDst) { Debug.Assert(typeSrc != null); Debug.Assert(typeSrc.IsInterfaceType || typeSrc.IsDelegateType); @@ -714,7 +670,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics AggregateSymbol aggSym = typeSrc.OwningAggregate; AggregateType aggOpenType = aggSym.getThisType(); - if (!semanticChecker.CheckTypeAccess(aggOpenType, context)) + if (!CSemanticChecker.CheckTypeAccess(aggOpenType, context)) { // if the aggregate symbol itself is not accessible, then forget it, there is no // variance that will help us arrive at an accessible type. @@ -728,7 +684,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics for (int i = 0; i < newTypeArgsTemp.Length; i++) { CType typeArg = typeArgs[i]; - if (semanticChecker.CheckTypeAccess(typeArg, context)) + if (CSemanticChecker.CheckTypeAccess(typeArg, context)) { // we have an accessible argument, this position is not a problem. newTypeArgsTemp[i] = typeArg; @@ -741,30 +697,30 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - newTypeArgsTemp[i] = GetBestAccessibleType(semanticChecker, context, typeArg); + newTypeArgsTemp[i] = GetBestAccessibleType(context, typeArg); // now we either have a value type (which must be accessible due to the above // check, OR we have an inaccessible type (which must be a ref type). In either // case, the recursion worked out and we are OK to vary this argument. } - TypeArray newTypeArgs = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp); + TypeArray newTypeArgs = TypeArray.Allocate(newTypeArgsTemp); CType intermediateType = GetAggregate(aggSym, typeSrc.OuterType, newTypeArgs); // All type arguments were varied successfully, which means now we must be accessible. But we could // have violated constraints. Let's check that out. - if (!TypeBind.CheckConstraints(semanticChecker, errHandling: null, intermediateType, CheckConstraintsFlags.NoErrors)) + if (!TypeBind.CheckConstraints(intermediateType, CheckConstraintsFlags.NoErrors)) { return false; } typeDst = intermediateType; - Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); + Debug.Assert(CSemanticChecker.CheckTypeAccess(typeDst, context)); return true; } - private bool TryArrayVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, ArrayType typeSrc, out CType typeDst) + private static bool TryArrayVarianceAdjustmentToGetAccessibleType(AggregateSymbol context, ArrayType typeSrc, out CType typeDst) { Debug.Assert(typeSrc != null); @@ -776,10 +732,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics // Covariant array conversions exist for reference types only. if (elementType.IsReferenceType) { - CType destElement = GetBestAccessibleType(semanticChecker, context, elementType); + CType destElement = GetBestAccessibleType(context, elementType); typeDst = GetArray(destElement, typeSrc.Rank, typeSrc.IsSZArray); - Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); + Debug.Assert(CSemanticChecker.CheckTypeAccess(typeDst, context)); return true; } @@ -787,17 +743,10 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics return false; } - public AggregateType ObjectAggregateType => (AggregateType)_symbolTable.GetCTypeFromType(typeof(object)); - - private readonly Dictionary, bool> _internalsVisibleToCalculated - = new Dictionary, bool>(); - - internal bool InternalsVisibleTo(Assembly assemblyThatDefinesAttribute, Assembly assemblyToCheck) + internal static bool InternalsVisibleTo(Assembly assemblyThatDefinesAttribute, Assembly assemblyToCheck) { - bool result; - - var key = Tuple.Create(assemblyThatDefinesAttribute, assemblyToCheck); - if (!_internalsVisibleToCalculated.TryGetValue(key, out result)) + (Assembly, Assembly) key = (assemblyThatDefinesAttribute, assemblyToCheck); + if (!s_internalsVisibleToCache.TryGetValue(key, out bool result)) { AssemblyName assyName; @@ -808,20 +757,17 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics try { assyName = assemblyToCheck.GetName(); + result = assemblyThatDefinesAttribute.GetCustomAttributes() + .OfType() + .Select(ivta => new AssemblyName(ivta.AssemblyName)) + .Any(an => AssemblyName.ReferenceMatchesDefinition(an, assyName)); } - catch (System.Security.SecurityException) + catch (SecurityException) { result = false; - goto SetMemo; } - result = assemblyThatDefinesAttribute.GetCustomAttributes() - .OfType() - .Select(ivta => new AssemblyName(ivta.AssemblyName)) - .Any(an => AssemblyName.ReferenceMatchesDefinition(an, assyName)); - - SetMemo: - _internalsVisibleToCalculated[key] = result; + s_internalsVisibleToCache[key] = result; } return result; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeTable.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeTable.cs index 6923781..c1a2f4a 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeTable.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Types/TypeTable.cs @@ -9,123 +9,120 @@ using System.Diagnostics.CodeAnalysis; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal readonly struct KeyPair : IEquatable> + internal static class TypeTable { - private readonly Key1 _pKey1; - private readonly Key2 _pKey2; - - public KeyPair(Key1 pKey1, Key2 pKey2) + private readonly struct KeyPair : IEquatable> { - _pKey1 = pKey1; - _pKey2 = pKey2; - } + private readonly TKey1 _pKey1; + private readonly TKey2 _pKey2; - public bool Equals(KeyPair other) - { - return EqualityComparer.Default.Equals(_pKey1, other._pKey1) - && EqualityComparer.Default.Equals(_pKey2, other._pKey2); - } + public KeyPair(TKey1 pKey1, TKey2 pKey2) + { + _pKey1 = pKey1; + _pKey2 = pKey2; + } -#if DEBUG - [ExcludeFromCodeCoverage] // Typed overload should always be the method called. -#endif - public override bool Equals(object obj) - { - Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); - if (!(obj is KeyPair)) return false; - return Equals((KeyPair)obj); - } + public bool Equals(KeyPair other) => + EqualityComparer.Default.Equals(_pKey1, other._pKey1) + && EqualityComparer.Default.Equals(_pKey2, other._pKey2); - public override int GetHashCode() - { - int hash = _pKey1 == null ? 0 : _pKey1.GetHashCode(); - return (hash << 5) - hash + (_pKey2 == null ? 0 : _pKey2.GetHashCode()); +#if DEBUG + [ExcludeFromCodeCoverage] // Typed overload should always be the method called. +#endif + public override bool Equals(object obj) + { + Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); + if (!(obj is KeyPair)) + { + return false; + } + + return Equals((KeyPair)obj); + } + + public override int GetHashCode() + { + int hash = _pKey1 == null ? 0 : _pKey1.GetHashCode(); + return (hash << 5) - hash + (_pKey2 == null ? 0 : _pKey2.GetHashCode()); + } } - } - internal sealed class TypeTable - { // Two way hashes - private readonly Dictionary>, AggregateType> _aggregateTable; - private readonly Dictionary, ArrayType> _pArrayTable; - private readonly Dictionary, ParameterModifierType> _pParameterModifierTable; + private static readonly Dictionary>, AggregateType> s_aggregateTable = + new Dictionary>, AggregateType>(); - // One way hashes - private readonly Dictionary _pPointerTable; - private readonly Dictionary _pNullableTable; + private static readonly Dictionary, ArrayType> s_arrayTable = + new Dictionary, ArrayType>(); - public TypeTable() - { - _aggregateTable = new Dictionary>, AggregateType>(); - _pArrayTable = new Dictionary, ArrayType>(); - _pParameterModifierTable = new Dictionary, ParameterModifierType>(); - _pPointerTable = new Dictionary(); - _pNullableTable = new Dictionary(); - } + private static readonly Dictionary, ParameterModifierType> s_parameterModifierTable = + new Dictionary, ParameterModifierType>(); + + // One way hashes + private static readonly Dictionary s_pointerTable = new Dictionary(); + private static readonly Dictionary s_nullableTable = new Dictionary(); private static KeyPair MakeKey(TKey1 key1, TKey2 key2) => new KeyPair(key1, key2); - public AggregateType LookupAggregate(AggregateSymbol aggregate, AggregateType outer, TypeArray args) + public static AggregateType LookupAggregate(AggregateSymbol aggregate, AggregateType outer, TypeArray args) { - _aggregateTable.TryGetValue(MakeKey(aggregate, MakeKey(outer, args)), out AggregateType result); + s_aggregateTable.TryGetValue(MakeKey(aggregate, MakeKey(outer, args)), out AggregateType result); return result; } - public void InsertAggregate( - AggregateSymbol aggregate, AggregateType outer, TypeArray args, AggregateType pAggregate) + public static void InsertAggregate(AggregateSymbol aggregate, AggregateType outer, TypeArray args, AggregateType ats) { Debug.Assert(LookupAggregate(aggregate, outer, args) == null); - _aggregateTable.Add(MakeKey(aggregate, MakeKey(outer, args)), pAggregate); + s_aggregateTable.Add(MakeKey(aggregate, MakeKey(outer, args)), ats); } // rankNum is 0 for SZ arrays, equal to rank otherwise. - public ArrayType LookupArray(CType pElementType, int rankNum) + public static ArrayType LookupArray(CType elementType, int rankNum) { - _pArrayTable.TryGetValue(new KeyPair(pElementType, rankNum), out ArrayType result); + s_arrayTable.TryGetValue(new KeyPair(elementType, rankNum), out ArrayType result); return result; } - public void InsertArray(CType pElementType, int rankNum, ArrayType pArray) + public static void InsertArray(CType elementType, int rankNum, ArrayType pArray) { - Debug.Assert(LookupArray(pElementType, rankNum) == null); - _pArrayTable.Add(new KeyPair(pElementType, rankNum), pArray); + Debug.Assert(LookupArray(elementType, rankNum) == null); + s_arrayTable.Add(new KeyPair(elementType, rankNum), pArray); } - public ParameterModifierType LookupParameterModifier(CType pElementType, bool isOut) + public static ParameterModifierType LookupParameterModifier(CType elementType, bool isOut) { - _pParameterModifierTable.TryGetValue(new KeyPair(pElementType, isOut), out ParameterModifierType result); + s_parameterModifierTable.TryGetValue(new KeyPair(elementType, isOut), out ParameterModifierType result); return result; } - public void InsertParameterModifier(CType pElementType, bool isOut, ParameterModifierType pParameterModifier) + public static void InsertParameterModifier(CType elementType, bool isOut, ParameterModifierType parameterModifier) { - Debug.Assert(LookupParameterModifier(pElementType, isOut) == null); - _pParameterModifierTable.Add(new KeyPair(pElementType, isOut), pParameterModifier); + Debug.Assert(LookupParameterModifier(elementType, isOut) == null); + s_parameterModifierTable.Add(new KeyPair(elementType, isOut), parameterModifier); } - public PointerType LookupPointer(CType pElementType) + public static PointerType LookupPointer(CType elementType) { - _pPointerTable.TryGetValue(pElementType, out PointerType result); + s_pointerTable.TryGetValue(elementType, out PointerType result); return result; } - public void InsertPointer(CType pElementType, PointerType pPointer) + public static void InsertPointer(CType elementType, PointerType pointer) { - Debug.Assert(LookupPointer(pElementType) == null); - _pPointerTable.Add(pElementType, pPointer); + Debug.Assert(LookupPointer(elementType) == null); + s_pointerTable.Add(elementType, pointer); } - public NullableType LookupNullable(CType pUnderlyingType) + public static NullableType LookupNullable(CType underlyingType) { - _pNullableTable.TryGetValue(pUnderlyingType, out NullableType result); + s_nullableTable.TryGetValue(underlyingType, out NullableType result); return result; } - public void InsertNullable(CType pUnderlyingType, NullableType pNullable) + public static void InsertNullable(CType underlyingType, NullableType nullable) { - Debug.Assert(LookupNullable(pUnderlyingType) == null); - _pNullableTable.Add(pUnderlyingType, pNullable); + Debug.Assert(LookupNullable(underlyingType) == null); + s_nullableTable.Add(underlyingType, nullable); } } } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/UnaOpSig.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/UnaOpSig.cs index 0542d12..9e55675 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/UnaOpSig.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/UnaOpSig.cs @@ -7,7 +7,7 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { - internal sealed partial class ExpressionBinder + internal readonly partial struct ExpressionBinder { private class UnaOpSig { @@ -58,7 +58,7 @@ namespace Microsoft.CSharp.RuntimeBinder.Semantics this.pfn = uos.pfn; this.fnkind = uos.fnkind; Debug.Assert(pt != PredefinedType.PT_UNDEFINEDINDEX); - _type = pt != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt) : null; + _type = pt != PredefinedType.PT_UNDEFINEDINDEX ? GetPredefindType(pt) : null; _grflt = LiftFlags.None; } public bool FPreDef() diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs index 323f25b..066d75f 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs @@ -15,72 +15,37 @@ using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder { - internal sealed class SymbolTable + internal static class SymbolTable { - ///////////////////////////////////////////////////////////////////////////////// - // Members - private readonly HashSet _typesWithConversionsLoaded = new HashSet(); - private readonly HashSet _namesLoadedForEachType = new HashSet(); - - // Members from the managed binder. - private readonly SYMTBL _symbolTable; - private readonly SymFactory _symFactory; - private readonly TypeManager _typeManager; - private readonly BSYMMGR _bsymmgr; - private readonly CSemanticChecker _semanticChecker; + private static readonly HashSet s_typesWithConversionsLoaded = new HashSet(); + private static readonly HashSet s_namesLoadedForEachType = new HashSet(); - ///////////////////////////////////////////////////////////////////////////////// - - private sealed class NameHashKey : IEquatable + private readonly struct NameHashKey : IEquatable { - internal readonly Type type; - internal readonly string name; + internal Type Type { get; } + internal string Name { get; } public NameHashKey(Type type, string name) { - this.type = type; - this.name = name; + Type = type; + Name = name; } - public bool Equals(NameHashKey other) => other != null && type.Equals(other.type) && name.Equals(other.name); + public bool Equals(NameHashKey other) => Type.Equals(other.Type) && Name.Equals(other.Name); -#if DEBUG +#if DEBUG [ExcludeFromCodeCoverage] // Typed overload should always be the method called. #endif public override bool Equals(object obj) { Debug.Fail("Sub-optimal overload called. Check if this can be avoided."); - return Equals(obj as NameHashKey); + return obj is NameHashKey key && Equals(key); } - public override int GetHashCode() - { - return type.GetHashCode() ^ name.GetHashCode(); - } + public override int GetHashCode() => Type.GetHashCode() ^ Name.GetHashCode(); } - ///////////////////////////////////////////////////////////////////////////////// - - internal SymbolTable( - SYMTBL symTable, - SymFactory symFactory, - TypeManager typeManager, - BSYMMGR bsymmgr, - CSemanticChecker semanticChecker) - { - _symbolTable = symTable; - _symFactory = symFactory; - _typeManager = typeManager; - _bsymmgr = bsymmgr; - _semanticChecker = semanticChecker; - - // Now populate object. - LoadSymbolsFromType(typeof(object)); - } - - ///////////////////////////////////////////////////////////////////////////////// - - internal void PopulateSymbolTableWithName( + internal static void PopulateSymbolTableWithName( string name, IEnumerable typeArguments, Type callingType) @@ -101,7 +66,7 @@ namespace Microsoft.CSharp.RuntimeBinder NameHashKey key = new NameHashKey(callingType, name); // If we've already populated this name/type pair, then just leave. - if (_namesLoadedForEachType.Contains(key)) + if (s_namesLoadedForEachType.Contains(key)) { return; } @@ -121,7 +86,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - internal SymWithType LookupMember( + internal static SymWithType LookupMember( string name, Expr callingObject, ParentSymbol context, @@ -134,7 +99,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (type is ArrayType) { - type = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY); + type = SymbolLoader.GetPredefindType(PredefinedType.PT_ARRAY); } if (type is NullableType nub) { @@ -142,7 +107,6 @@ namespace Microsoft.CSharp.RuntimeBinder } if (!mem.Lookup( - _semanticChecker, type, callingObject, context, @@ -158,7 +122,7 @@ namespace Microsoft.CSharp.RuntimeBinder return mem.SwtFirst(); } - private void AddParameterConversions(MethodBase method) + private static void AddParameterConversions(MethodBase method) { foreach (ParameterInfo param in method.GetParameters()) { @@ -167,20 +131,20 @@ namespace Microsoft.CSharp.RuntimeBinder } #region InheritanceHierarchy - private void AddNamesOnType(NameHashKey key) + private static void AddNamesOnType(NameHashKey key) { - Debug.Assert(!_namesLoadedForEachType.Contains(key)); + Debug.Assert(!s_namesLoadedForEachType.Contains(key)); // We need to declare all of its inheritance hierarchy. - List inheritance = CreateInheritanceHierarchyList(key.type); + List inheritance = CreateInheritanceHierarchyList(key.Type); // Now add every method as it appears in the inheritance hierarchy. - AddNamesInInheritanceHierarchy(key.name, inheritance); + AddNamesInInheritanceHierarchy(key.Name, inheritance); } ///////////////////////////////////////////////////////////////////////////////// - private void AddNamesInInheritanceHierarchy(string name, List inheritance) + private static void AddNamesInInheritanceHierarchy(string name, List inheritance) { for (int i = inheritance.Count - 1; i >= 0; --i) { @@ -190,7 +154,7 @@ namespace Microsoft.CSharp.RuntimeBinder type = type.GetGenericTypeDefinition(); } - if (!_namesLoadedForEachType.Add(new NameHashKey(type, name))) + if (!s_namesLoadedForEachType.Add(new NameHashKey(type, name))) { continue; } @@ -275,7 +239,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private List CreateInheritanceHierarchyList(Type type) + private static List CreateInheritanceHierarchyList(Type type) { List list; if (type.IsInterface) @@ -315,11 +279,8 @@ namespace Microsoft.CSharp.RuntimeBinder CType ctype = GetCTypeFromType(type); if (ctype.IsWindowsRuntimeType) { - TypeArray collectioniFaces = ((AggregateType)ctype).GetWinRTCollectionIfacesAll(_semanticChecker.SymbolLoader); - - for (int i = 0; i < collectioniFaces.Count; i++) + foreach (CType collectionType in ((AggregateType)ctype).WinRTCollectionIfacesAll.Items) { - CType collectionType = collectioniFaces[i]; Debug.Assert(collectionType.IsInterfaceType); // Insert into our list of Types. @@ -333,14 +294,11 @@ namespace Microsoft.CSharp.RuntimeBinder #region GetName ///////////////////////////////////////////////////////////////////////////////// - private Name GetName(string p) - { - return NameManager.Add(p ?? ""); - } + private static Name GetName(string p) => NameManager.Add(p ?? ""); ///////////////////////////////////////////////////////////////////////////////// - private Name GetName(Type type) + private static Name GetName(Type type) { string name = type.Name; if (type.IsGenericType) @@ -360,7 +318,7 @@ namespace Microsoft.CSharp.RuntimeBinder #region TypeParameters ///////////////////////////////////////////////////////////////////////////////// - private TypeArray GetMethodTypeParameters(MethodInfo method, MethodSymbol parent) + private static TypeArray GetMethodTypeParameters(MethodInfo method, MethodSymbol parent) { if (method.IsGenericMethod) { @@ -376,16 +334,18 @@ namespace Microsoft.CSharp.RuntimeBinder for (int i = 0; i < genericArguments.Length; i++) { Type t = genericArguments[i]; - ((TypeParameterType)ctypes[i]).Symbol.SetBounds(_bsymmgr.AllocParams(GetCTypeArrayFromTypes(t.GetGenericParameterConstraints()))); + ((TypeParameterType)ctypes[i]).Symbol.SetBounds(TypeArray.Allocate(GetCTypeArrayFromTypes(t.GetGenericParameterConstraints()))); } - return _bsymmgr.AllocParams(ctypes.Length, ctypes); + + return TypeArray.Allocate(ctypes); } - return BSYMMGR.EmptyTypeArray(); + + return TypeArray.Empty; } ///////////////////////////////////////////////////////////////////////////////// - private TypeArray GetAggregateTypeParameters(Type type, AggregateSymbol agg) + private static TypeArray GetAggregateTypeParameters(Type type, AggregateSymbol agg) { if (type.IsGenericType) { @@ -433,21 +393,23 @@ namespace Microsoft.CSharp.RuntimeBinder ctypes.Add(ctype); } } - return _bsymmgr.AllocParams(ctypes.Count, ctypes.ToArray()); + + return TypeArray.Allocate(ctypes.ToArray()); } - return BSYMMGR.EmptyTypeArray(); + + return TypeArray.Empty; } ///////////////////////////////////////////////////////////////////////////////// - private TypeParameterType LoadClassTypeParameter(AggregateSymbol parent, Type t) + private static TypeParameterType LoadClassTypeParameter(AggregateSymbol parent, Type t) { for (AggregateSymbol p = parent; p != null; p = p.parent as AggregateSymbol) { - for (TypeParameterSymbol typeParam = _bsymmgr.LookupAggMember( + for (TypeParameterSymbol typeParam = SymbolStore.LookupSym( GetName(t), p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol; typeParam != null; - typeParam = BSYMMGR.LookupNextSym(typeParam, p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol) + typeParam = typeParam.LookupNext(symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol) { if (AreTypeParametersEquivalent(typeParam.GetTypeParameterType().AssociatedSystemType, t)) { @@ -460,7 +422,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private bool AreTypeParametersEquivalent(Type t1, Type t2) + private static bool AreTypeParametersEquivalent(Type t1, Type t2) { Debug.Assert(t1.IsGenericParameter && t2.IsGenericParameter); @@ -510,7 +472,7 @@ namespace Microsoft.CSharp.RuntimeBinder // return the type parameter type given if it is in a method, we do not try to // generalize these occurrences for reference equality. // - private Type GetOriginalTypeParameterType(Type t) + private static Type GetOriginalTypeParameterType(Type t) { Debug.Assert(t.IsGenericParameter); @@ -553,19 +515,17 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private TypeParameterType LoadMethodTypeParameter(MethodSymbol parent, Type t) + private static TypeParameterType LoadMethodTypeParameter(MethodSymbol parent, Type t) { for (Symbol sym = parent.firstChild; sym != null; sym = sym.nextChild) { - if (!(sym is TypeParameterSymbol parSym)) - { - continue; - } - - TypeParameterType type = parSym.GetTypeParameterType(); - if (AreTypeParametersEquivalent(type.AssociatedSystemType, t)) + if (sym is TypeParameterSymbol parSym) { - return type; + TypeParameterType type = parSym.GetTypeParameterType(); + if (AreTypeParametersEquivalent(type.AssociatedSystemType, t)) + { + return type; + } } } @@ -574,7 +534,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private TypeParameterType AddTypeParameterToSymbolTable( + private static TypeParameterType AddTypeParameterToSymbolTable( AggregateSymbol agg, MethodSymbol meth, Type t, @@ -585,7 +545,7 @@ namespace Microsoft.CSharp.RuntimeBinder TypeParameterSymbol typeParam; if (bIsAggregate) { - typeParam = _symFactory.CreateClassTypeParameter( + typeParam = SymFactory.CreateClassTypeParameter( GetName(t), agg, t.GenericParameterPosition, @@ -593,7 +553,7 @@ namespace Microsoft.CSharp.RuntimeBinder } else { - typeParam = _symFactory.CreateMethodTypeParameter( + typeParam = SymFactory.CreateMethodTypeParameter( GetName(t), meth, t.GenericParameterPosition, @@ -626,7 +586,7 @@ namespace Microsoft.CSharp.RuntimeBinder typeParam.SetConstraints(cons); typeParam.SetAccess(ACCESS.ACC_PUBLIC); - TypeParameterType typeParamType = _typeManager.GetTypeParameter(typeParam); + TypeParameterType typeParamType = TypeManager.GetTypeParameter(typeParam); return typeParamType; } @@ -636,7 +596,7 @@ namespace Microsoft.CSharp.RuntimeBinder #region LoadTypeChain ///////////////////////////////////////////////////////////////////////////////// - private CType LoadSymbolsFromType(Type type) + private static CType LoadSymbolsFromType(Type type) { List declarationChain = BuildDeclarationChain(type); @@ -651,11 +611,11 @@ namespace Microsoft.CSharp.RuntimeBinder { if (t.IsNullableType()) { - return _typeManager.GetNullable(GetCTypeFromType(t.GetGenericArguments()[0])); + return TypeManager.GetNullable(GetCTypeFromType(t.GetGenericArguments()[0])); } AggregateSymbol next = FindSymForType( - _symbolTable.LookupSym(GetName(t), current, symbmask_t.MASK_AggregateSymbol), t); + SymbolStore.LookupSym(GetName(t), current, symbmask_t.MASK_AggregateSymbol), t); // If we haven't found this type yet, then add it to our symbol table. if (next == null) @@ -700,7 +660,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private TypeParameterType ProcessMethodTypeParameter(MethodInfo methinfo, Type t, AggregateSymbol parent) + private static TypeParameterType ProcessMethodTypeParameter(MethodInfo methinfo, Type t, AggregateSymbol parent) { MethodSymbol meth = FindMatchingMethod(methinfo, parent); if (meth == null) @@ -713,12 +673,13 @@ namespace Microsoft.CSharp.RuntimeBinder // type parameter on it. Debug.Assert(meth != null); } + return LoadMethodTypeParameter(meth, t); } ///////////////////////////////////////////////////////////////////////////////// - private CType GetConstructedType(Type type, AggregateSymbol agg) + private static CType GetConstructedType(Type type, AggregateSymbol agg) { // We've found the one we want, so return it. if (type.IsGenericType) @@ -731,8 +692,8 @@ namespace Microsoft.CSharp.RuntimeBinder types.Add(GetCTypeFromType(argument)); } - TypeArray typeArray = _bsymmgr.AllocParams(types.ToArray()); - AggregateType aggType = _typeManager.GetAggregate(agg, typeArray); + TypeArray typeArray = TypeArray.Allocate(types.ToArray()); + AggregateType aggType = TypeManager.GetAggregate(agg, typeArray); return aggType; } CType ctype = agg.getThisType(); @@ -741,7 +702,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private CType ProcessSpecialTypeInChain(NamespaceOrAggregateSymbol parent, Type t) + private static CType ProcessSpecialTypeInChain(NamespaceOrAggregateSymbol parent, Type t) { if (t.IsGenericParameter) { @@ -753,7 +714,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (t.IsArray) { // Now we return an array of nesting level corresponding to the rank. - return _typeManager.GetArray( + return TypeManager.GetArray( GetCTypeFromType(t.GetElementType()), t.GetArrayRank(), #if netcoreapp @@ -767,7 +728,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (t.IsPointer) { // Now we return the pointer type that we want. - return _typeManager.GetPointer(GetCTypeFromType(t.GetElementType())); + return TypeManager.GetPointer(GetCTypeFromType(t.GetElementType())); } return null; @@ -839,7 +800,7 @@ namespace Microsoft.CSharp.RuntimeBinder // to lookup names of types for real (only names of members). // For either case, move onto the next symbol in the chain, and check again for appropriate type. - private AggregateSymbol FindSymForType(Symbol sym, Type t) + private static AggregateSymbol FindSymForType(Symbol sym, Type t) { while (sym != null) { @@ -856,18 +817,18 @@ namespace Microsoft.CSharp.RuntimeBinder return null; } - private NamespaceSymbol AddNamespaceToSymbolTable(NamespaceOrAggregateSymbol parent, string sz) + private static NamespaceSymbol AddNamespaceToSymbolTable(NamespaceOrAggregateSymbol parent, string sz) { Name name = GetName(sz); - return _symbolTable.LookupSym(name, parent, symbmask_t.MASK_NamespaceSymbol) as NamespaceSymbol - ?? _symFactory.CreateNamespace(name, parent as NamespaceSymbol); + return SymbolStore.LookupSym(name, parent, symbmask_t.MASK_NamespaceSymbol) as NamespaceSymbol + ?? SymFactory.CreateNamespace(name, parent as NamespaceSymbol); } #endregion #region CTypeFromType ///////////////////////////////////////////////////////////////////////////////// - internal CType[] GetCTypeArrayFromTypes(Type[] types) + internal static CType[] GetCTypeArrayFromTypes(Type[] types) { Debug.Assert(types != null); @@ -890,8 +851,8 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - internal CType GetCTypeFromType(Type type) => type.IsByRef - ? _typeManager.GetParameterModifier(LoadSymbolsFromType(type.GetElementType()), false) + internal static CType GetCTypeFromType(Type type) => type.IsByRef + ? TypeManager.GetParameterModifier(LoadSymbolsFromType(type.GetElementType()), false) : LoadSymbolsFromType(type); #endregion @@ -899,11 +860,11 @@ namespace Microsoft.CSharp.RuntimeBinder #region Aggregates ///////////////////////////////////////////////////////////////////////////////// - private AggregateSymbol AddAggregateToSymbolTable( + private static AggregateSymbol AddAggregateToSymbolTable( NamespaceOrAggregateSymbol parent, Type type) { - AggregateSymbol agg = _symFactory.CreateAggregate(GetName(type), parent, _typeManager); + AggregateSymbol agg = SymFactory.CreateAggregate(GetName(type), parent); agg.AssociatedSystemType = type.IsGenericType ? type.GetGenericTypeDefinition() : type; agg.AssociatedAssembly = type.Assembly; @@ -941,7 +902,7 @@ namespace Microsoft.CSharp.RuntimeBinder } } agg.SetAggKind(kind); - agg.SetTypeVars(BSYMMGR.EmptyTypeArray()); + agg.SetTypeVars(TypeArray.Empty); ACCESS access; if (type.IsPublic) @@ -1000,7 +961,7 @@ namespace Microsoft.CSharp.RuntimeBinder Type t = genericArguments[i]; if (agg.GetTypeVars()[i] is TypeParameterType typeVar) { - typeVar.Symbol.SetBounds(_bsymmgr.AllocParams(GetCTypeArrayFromTypes(t.GetGenericParameterConstraints()))); + typeVar.Symbol.SetBounds(TypeArray.Allocate(GetCTypeArrayFromTypes(t.GetGenericParameterConstraints()))); } } } @@ -1034,7 +995,7 @@ namespace Microsoft.CSharp.RuntimeBinder } agg.SetBaseClass((AggregateType)GetCTypeFromType(t)); } - agg.SetTypeManager(_typeManager); + agg.SetFirstUDConversion(null); SetInterfacesOnAggregate(agg, type); agg.SetHasPubNoArgCtor(type.GetConstructor(Type.EmptyTypes) != null); @@ -1051,7 +1012,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void SetInterfacesOnAggregate(AggregateSymbol aggregate, Type type) + private static void SetInterfacesOnAggregate(AggregateSymbol aggregate, Type type) { if (type.IsGenericType) { @@ -1067,7 +1028,7 @@ namespace Microsoft.CSharp.RuntimeBinder // we don't really care where they've come from as long as we know the overall // set of IfacesAll. - aggregate.SetIfaces(_bsymmgr.AllocParams(interfaces.Length, GetCTypeArrayFromTypes(interfaces))); + aggregate.SetIfaces(TypeArray.Allocate(GetCTypeArrayFromTypes(interfaces))); aggregate.SetIfacesAll(aggregate.GetIfaces()); } #endregion @@ -1075,9 +1036,9 @@ namespace Microsoft.CSharp.RuntimeBinder #region Field ///////////////////////////////////////////////////////////////////////////////// - private FieldSymbol AddFieldToSymbolTable(FieldInfo fieldInfo, AggregateSymbol aggregate) + private static FieldSymbol AddFieldToSymbolTable(FieldInfo fieldInfo, AggregateSymbol aggregate) { - FieldSymbol field = _symbolTable.LookupSym( + FieldSymbol field = SymbolStore.LookupSym( GetName(fieldInfo.Name), aggregate, symbmask_t.MASK_FieldSymbol) as FieldSymbol; @@ -1086,7 +1047,7 @@ namespace Microsoft.CSharp.RuntimeBinder return field; } - field = _symFactory.CreateMemberVar(GetName(fieldInfo.Name), aggregate); + field = SymFactory.CreateMemberVar(GetName(fieldInfo.Name), aggregate); field.AssociatedFieldInfo = fieldInfo; field.isStatic = fieldInfo.IsStatic; @@ -1160,7 +1121,9 @@ namespace Microsoft.CSharp.RuntimeBinder private static Type GetTypeByName(ref Type cachedResult, string name) { +#pragma warning disable 252 if ((object)cachedResult == s_Sentinel) +#pragma warning restore 252 { System.Threading.Interlocked.CompareExchange(ref cachedResult, Type.GetType(name, throwOnError: false), s_Sentinel); } @@ -1168,9 +1131,9 @@ namespace Microsoft.CSharp.RuntimeBinder return cachedResult; } - private void AddEventToSymbolTable(EventInfo eventInfo, AggregateSymbol aggregate, FieldSymbol addedField) + private static void AddEventToSymbolTable(EventInfo eventInfo, AggregateSymbol aggregate, FieldSymbol addedField) { - EventSymbol ev = _symbolTable.LookupSym( + EventSymbol ev = SymbolStore.LookupSym( GetName(eventInfo.Name), aggregate, symbmask_t.MASK_EventSymbol) as EventSymbol; @@ -1180,7 +1143,7 @@ namespace Microsoft.CSharp.RuntimeBinder return; } - ev = _symFactory.CreateEvent(GetName(eventInfo.Name), aggregate); + ev = SymFactory.CreateEvent(GetName(eventInfo.Name), aggregate); ev.AssociatedEventInfo = eventInfo; // EventSymbol @@ -1245,7 +1208,7 @@ namespace Microsoft.CSharp.RuntimeBinder #region Properties ///////////////////////////////////////////////////////////////////////////////// - internal void AddPredefinedPropertyToSymbolTable(AggregateSymbol type, Name property) + internal static void AddPredefinedPropertyToSymbolTable(AggregateSymbol type, Name property) { AggregateType aggtype = type.getThisType(); Type t = aggtype.AssociatedSystemType; @@ -1260,7 +1223,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void AddPropertyToSymbolTable(PropertyInfo property, AggregateSymbol aggregate) + private static void AddPropertyToSymbolTable(PropertyInfo property, AggregateSymbol aggregate) { Name name; bool isIndexer = property.GetIndexParameters().Length != 0 @@ -1275,7 +1238,7 @@ namespace Microsoft.CSharp.RuntimeBinder { name = GetName(property.Name); } - PropertySymbol prop = _symbolTable.LookupSym( + PropertySymbol prop = SymbolStore.LookupSym( name, aggregate, symbmask_t.MASK_PropertySymbol) as PropertySymbol; @@ -1296,7 +1259,7 @@ namespace Microsoft.CSharp.RuntimeBinder } prevProp = prop; - prop = SymbolLoader.LookupNextSym(prop, prop.parent, symbmask_t.MASK_PropertySymbol) as PropertySymbol; + prop = prop.LookupNext(symbmask_t.MASK_PropertySymbol) as PropertySymbol; } prop = prevProp; @@ -1325,13 +1288,13 @@ namespace Microsoft.CSharp.RuntimeBinder { if (isIndexer) { - prop = _semanticChecker.SymbolLoader.GetGlobalSymbolFactory().CreateIndexer(name, aggregate, GetName(property.Name)); + prop = SymFactory.CreateIndexer(name, aggregate); prop.Params = CreateParameterArray(null, property.GetIndexParameters()); } else { - prop = _symFactory.CreateProperty(GetName(property.Name), aggregate); - prop.Params = BSYMMGR.EmptyTypeArray(); + prop = SymFactory.CreateProperty(GetName(property.Name), aggregate); + prop.Params = TypeArray.Empty; } } prop.AssociatedPropertyInfo = property; @@ -1409,7 +1372,7 @@ namespace Microsoft.CSharp.RuntimeBinder #region Methods ///////////////////////////////////////////////////////////////////////////////// - internal void AddPredefinedMethodToSymbolTable(AggregateSymbol type, Name methodName) + internal static void AddPredefinedMethodToSymbolTable(AggregateSymbol type, Name methodName) { Type t = type.getThisType().AssociatedSystemType; @@ -1442,7 +1405,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private MethodSymbol AddMethodToSymbolTable(MethodBase member, AggregateSymbol callingAggregate, MethodKindEnum kind) + private static MethodSymbol AddMethodToSymbolTable(MethodBase member, AggregateSymbol callingAggregate, MethodKindEnum kind) { MethodInfo method = member as MethodInfo; @@ -1473,7 +1436,7 @@ namespace Microsoft.CSharp.RuntimeBinder ParameterInfo[] parameters = member.GetParameters(); // First create the method. - methodSymbol = _symFactory.CreateMethod(GetName(member.Name), callingAggregate); + methodSymbol = SymFactory.CreateMethod(GetName(member.Name), callingAggregate); methodSymbol.AssociatedMemberInfo = member; methodSymbol.SetMethKind(kind); if (kind == MethodKindEnum.ExplicitConv || kind == MethodKindEnum.ImplicitConv) @@ -1524,7 +1487,7 @@ namespace Microsoft.CSharp.RuntimeBinder } else { - methodSymbol.typeVars = BSYMMGR.EmptyTypeArray(); + methodSymbol.typeVars = TypeArray.Empty; methodSymbol.isOverride = false; methodSymbol.isOperator = false; methodSymbol.swtSlot = null; @@ -1545,7 +1508,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void SetParameterDataForMethProp(MethodOrPropertySymbol methProp, ParameterInfo[] parameters) + private static void SetParameterDataForMethProp(MethodOrPropertySymbol methProp, ParameterInfo[] parameters) { if (parameters.Length > 0) { @@ -1568,7 +1531,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void SetParameterAttributes(MethodOrPropertySymbol methProp, ParameterInfo[] parameters, int i) + private static void SetParameterAttributes(MethodOrPropertySymbol methProp, ParameterInfo[] parameters, int i) { ParameterInfo parameter = parameters[i]; if ((parameter.Attributes & ParameterAttributes.Optional) != 0 && !parameter.ParameterType.IsByRef) @@ -1593,7 +1556,7 @@ namespace Microsoft.CSharp.RuntimeBinder { // Get DateTimeConstant ConstVal cv = ConstVal.Get(((DateTime)dateAttr.Value).Ticks); - CType cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_DATETIME); + CType cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_DATETIME); methProp.SetDefaultParameterValue(i, cvType, cv); } else @@ -1603,7 +1566,7 @@ namespace Microsoft.CSharp.RuntimeBinder { // Get DecimalConstant ConstVal cv = ConstVal.Get(decAttr.Value); - CType cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_DECIMAL); + CType cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_DECIMAL); methProp.SetDefaultParameterValue(i, cvType, cv); } else if ((parameter.Attributes & ParameterAttributes.HasDefault) != 0 && !parameter.ParameterType.IsByRef) @@ -1612,7 +1575,7 @@ namespace Microsoft.CSharp.RuntimeBinder // looking at isn't a by ref type or a type parameter. ConstVal cv = default(ConstVal); - CType cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT); + CType cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT); // We need to use RawDefaultValue, because DefaultValue is too clever. #if UNSUPPORTEDAPI @@ -1630,67 +1593,67 @@ namespace Microsoft.CSharp.RuntimeBinder case TypeCode.Byte: cv = ConstVal.Get((byte)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_BYTE); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_BYTE); break; case TypeCode.Int16: cv = ConstVal.Get((short)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_SHORT); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_SHORT); break; case TypeCode.Int32: cv = ConstVal.Get((int)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_INT); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_INT); break; case TypeCode.Int64: cv = ConstVal.Get((long)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_LONG); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_LONG); break; case TypeCode.Single: cv = ConstVal.Get((float)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_FLOAT); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_FLOAT); break; case TypeCode.Double: cv = ConstVal.Get((double)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_DOUBLE); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_DOUBLE); break; case TypeCode.Char: cv = ConstVal.Get((char)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_CHAR); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_CHAR); break; case TypeCode.Boolean: cv = ConstVal.Get((bool)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_BOOL); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_BOOL); break; case TypeCode.SByte: cv = ConstVal.Get((sbyte)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_SBYTE); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_SBYTE); break; case TypeCode.UInt16: cv = ConstVal.Get((ushort)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_USHORT); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_USHORT); break; case TypeCode.UInt32: cv = ConstVal.Get((uint)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_UINT); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_UINT); break; case TypeCode.UInt64: cv = ConstVal.Get((ulong)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_ULONG); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_ULONG); break; case TypeCode.String: cv = ConstVal.Get((string)defValue); - cvType = _semanticChecker.SymbolLoader.GetPredefindType(PredefinedType.PT_STRING); + cvType = SymbolLoader.GetPredefindType(PredefinedType.PT_STRING); break; } @@ -1705,23 +1668,25 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private MethodSymbol FindMatchingMethod(MemberInfo method, AggregateSymbol callingAggregate) + private static MethodSymbol FindMatchingMethod(MemberInfo method, AggregateSymbol callingAggregate) { - MethodSymbol meth = _bsymmgr.LookupAggMember(GetName(method.Name), callingAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; + MethodSymbol meth = SymbolStore.LookupSym(GetName(method.Name), callingAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; while (meth != null) { if (meth.AssociatedMemberInfo.IsEquivalentTo(method)) { return meth; } - meth = BSYMMGR.LookupNextSym(meth, callingAggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; + + meth = meth.LookupNext(symbmask_t.MASK_MethodSymbol) as MethodSymbol; } + return null; } ///////////////////////////////////////////////////////////////////////////////// - private uint GetCountOfModOpts(ParameterInfo[] parameters) + private static uint GetCountOfModOpts(ParameterInfo[] parameters) { uint count = 0; #if UNSUPPORTEDAPI @@ -1738,7 +1703,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private TypeArray CreateParameterArray(MemberInfo associatedInfo, ParameterInfo[] parameters) + private static TypeArray CreateParameterArray(MemberInfo associatedInfo, ParameterInfo[] parameters) { bool isVarArg = associatedInfo is MethodBase mb && (mb.CallingConvention & CallingConventions.VarArgs) != 0; CType[] types = new CType[isVarArg ? parameters.Length + 1 : parameters.Length]; @@ -1753,12 +1718,12 @@ namespace Microsoft.CSharp.RuntimeBinder types[types.Length - 1] = ArgumentListType.Instance; } - return _bsymmgr.AllocParams(types); + return TypeArray.Allocate(types); } ///////////////////////////////////////////////////////////////////////////////// - private CType GetTypeOfParameter(ParameterInfo p, MemberInfo m) + private static CType GetTypeOfParameter(ParameterInfo p, MemberInfo m) { Type t = p.ParameterType; CType ctype; @@ -1776,7 +1741,7 @@ namespace Microsoft.CSharp.RuntimeBinder if (ctype is ParameterModifierType mod && p.IsOut && !p.IsIn) { CType parameterType = mod.ParameterType; - ctype = _typeManager.GetParameterModifier(parameterType, true); + ctype = TypeManager.GetParameterModifier(parameterType, true); } return ctype; @@ -1784,7 +1749,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private bool DoesMethodHaveParameterArray(ParameterInfo[] parameters) + private static bool DoesMethodHaveParameterArray(ParameterInfo[] parameters) { if (parameters.Length == 0) { @@ -1806,7 +1771,7 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private SymWithType GetSlotForOverride(MethodInfo method) + private static SymWithType GetSlotForOverride(MethodInfo method) { if (method.IsVirtual && method.IsHideBySig) { @@ -1833,20 +1798,20 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private MethodSymbol FindMethodFromMemberInfo(MemberInfo baseMemberInfo) + private static MethodSymbol FindMethodFromMemberInfo(MemberInfo baseMemberInfo) { CType t = GetCTypeFromType(baseMemberInfo.DeclaringType); Debug.Assert(t is AggregateType); AggregateSymbol aggregate = ((AggregateType)t).OwningAggregate; Debug.Assert(aggregate != null); - MethodSymbol meth = _semanticChecker.SymbolLoader.LookupAggMember( + MethodSymbol meth = SymbolLoader.LookupAggMember( GetName(baseMemberInfo.Name), aggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol; for (; meth != null && !meth.AssociatedMemberInfo.IsEquivalentTo(baseMemberInfo); - meth = SymbolLoader.LookupNextSym(meth, aggregate, symbmask_t.MASK_MethodSymbol) as MethodSymbol) + meth = meth.LookupNext(symbmask_t.MASK_MethodSymbol) as MethodSymbol) ; return meth; @@ -1854,16 +1819,15 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - internal bool AggregateContainsMethod(AggregateSymbol agg, string szName, symbmask_t mask) - { - return _semanticChecker.SymbolLoader.LookupAggMember(GetName(szName), agg, mask) != null; - } + internal static bool AggregateContainsMethod(AggregateSymbol agg, string szName, symbmask_t mask) => + SymbolLoader.LookupAggMember(GetName(szName), agg, mask) != null; + #endregion #region Conversions ///////////////////////////////////////////////////////////////////////////////// - internal void AddConversionsForType(Type type) + internal static void AddConversionsForType(Type type) { if (type.IsInterface) { @@ -1877,14 +1841,14 @@ namespace Microsoft.CSharp.RuntimeBinder ///////////////////////////////////////////////////////////////////////////////// - private void AddConversionsForOneType(Type type) + private static void AddConversionsForOneType(Type type) { if (type.IsGenericType) { type = type.GetGenericTypeDefinition(); } - if (!_typesWithConversionsLoaded.Add(type)) + if (!s_typesWithConversionsLoaded.Add(type)) { return; } -- 2.7.4