Example #1
0
        private Dictionary <string, ImmutableArray <NamedTypeSymbol> > GetNameToTypeMembersMap()
        {
            if (_nameToTypeMembersMap == null)
            {
                // NOTE: This method depends on MakeNameToMembersMap() on creating a proper
                // NOTE: type of the array, see comments in MakeNameToMembersMap() for details

                var dictionary = new Dictionary <string, ImmutableArray <NamedTypeSymbol> >(StringOrdinalComparer.Instance);

                Dictionary <string, ImmutableArray <NamespaceOrTypeSymbol> > map = this.GetNameToMembersMap();
                foreach (var kvp in map)
                {
                    ImmutableArray <NamespaceOrTypeSymbol> members = kvp.Value;

                    foreach (var symbol in members)
                    {
                        if (symbol.Kind != SymbolKind.NamedType)
                        {
                            throw new System.Exception($"Only named types are allowed in Templates, found {symbol.Kind}");
                        }
                    }

                    dictionary.Add(kvp.Key, members.As <NamedTypeSymbol>());
                }

                Interlocked.CompareExchange(ref _nameToTypeMembersMap, dictionary, null);
            }

            return(_nameToTypeMembersMap);
        }
Example #2
0
        private Dictionary <string, ImmutableArray <NamedTypeSymbol> > GetNameToTypeMembersMap()
        {
            if (_nameToTypeMembersMap == null)
            {
                // NOTE: This method depends on MakeNameToMembersMap() on creating a proper
                // NOTE: type of the array, see comments in MakeNameToMembersMap() for details

#if XSHARP
                var dictionary = new Dictionary <String, ImmutableArray <NamedTypeSymbol> >(XSharpString.Comparer);
#else
                var dictionary = new Dictionary <String, ImmutableArray <NamedTypeSymbol> >(StringOrdinalComparer.Instance);
#endif

                Dictionary <String, ImmutableArray <NamespaceOrTypeSymbol> > map = this.GetNameToMembersMap();
                foreach (var kvp in map)
                {
                    ImmutableArray <NamespaceOrTypeSymbol> members = kvp.Value;

                    bool hasType      = false;
                    bool hasNamespace = false;

                    foreach (var symbol in members)
                    {
                        if (symbol.Kind == SymbolKind.NamedType)
                        {
                            hasType = true;
                            if (hasNamespace)
                            {
                                break;
                            }
                        }
                        else
                        {
                            Debug.Assert(symbol.Kind == SymbolKind.Namespace);
                            hasNamespace = true;
                            if (hasType)
                            {
                                break;
                            }
                        }
                    }

                    if (hasType)
                    {
                        if (hasNamespace)
                        {
                            dictionary.Add(kvp.Key, members.OfType <NamedTypeSymbol>().AsImmutable());
                        }
                        else
                        {
                            dictionary.Add(kvp.Key, members.As <NamedTypeSymbol>());
                        }
                    }
                }

                Interlocked.CompareExchange(ref _nameToTypeMembersMap, dictionary, null);
            }

            return(_nameToTypeMembersMap);
        }
Example #3
0
        internal EEMethodSymbol(
            EENamedTypeSymbol container,
            string name,
            Location location,
            MethodSymbol sourceMethod,
            ImmutableArray <LocalSymbol> sourceLocals,
            ImmutableArray <LocalSymbol> sourceLocalsForBinding,
            ImmutableDictionary <string, DisplayClassVariable> sourceDisplayClassVariables,
            GenerateMethodBody generateMethodBody)
        {
            Debug.Assert(sourceMethod.IsDefinition);
            Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition);
            Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod));

            _container = container;
            _name      = name;
            _locations = ImmutableArray.Create(location);

            // What we want is to map all original type parameters to the corresponding new type parameters
            // (since the old ones have the wrong owners).  Unfortunately, we have a circular dependency:
            //   1) Each new type parameter requires the entire map in order to be able to construct its constraint list.
            //   2) The map cannot be constructed until all new type parameters exist.
            // Our solution is to pass each new type parameter a lazy reference to the type map.  We then
            // initialize the map as soon as the new type parameters are available - and before they are
            // handed out - so that there is never a period where they can require the type map and find
            // it uninitialized.

            var sourceMethodTypeParameters = sourceMethod.TypeParameters;
            var allSourceTypeParameters    = container.SourceTypeParameters.Concat(sourceMethodTypeParameters);

            var getTypeMap = new Func <TypeMap>(() => this.TypeMap);

            _typeParameters = sourceMethodTypeParameters.SelectAsArray(
                (tp, i, arg) => (TypeParameterSymbol) new EETypeParameterSymbol(this, tp, i, getTypeMap),
                (object)null);
            _allTypeParameters = container.TypeParameters.Concat(_typeParameters);
            this.TypeMap       = new TypeMap(allSourceTypeParameters, _allTypeParameters);

            EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);

            var substitutedSourceType = container.SubstitutedSourceType;

            this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType);
            if (sourceMethod.Arity > 0)
            {
                this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As <TypeSymbol>());
            }
            TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters);

            // Create a map from original parameter to target parameter.
            var parameterBuilder = ArrayBuilder <ParameterSymbol> .GetInstance();

            var substitutedSourceThisParameter    = this.SubstitutedSourceMethod.ThisParameter;
            var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null;

            if (substitutedSourceHasThisParameter)
            {
                _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter);
                Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType);
                parameterBuilder.Add(_thisParameter);
            }

            var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0);

            foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters)
            {
                var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset;
                Debug.Assert(ordinal == parameterBuilder.Count);
                var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter);
                parameterBuilder.Add(parameter);
            }

            _parameters = parameterBuilder.ToImmutableAndFree();

            var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            var localsMap = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocals)
            {
                var local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                localsMap.Add(sourceLocal, local);
                localsBuilder.Add(local);
            }
            this.Locals   = localsBuilder.ToImmutableAndFree();
            localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocalsForBinding)
            {
                LocalSymbol local;
                if (!localsMap.TryGetValue(sourceLocal, out local))
                {
                    local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                    localsMap.Add(sourceLocal, local);
                }
                localsBuilder.Add(local);
            }
            this.LocalsForBinding = localsBuilder.ToImmutableAndFree();

            // Create a map from variable name to display class field.
            var displayClassVariables = PooledDictionary <string, DisplayClassVariable> .GetInstance();

            foreach (var pair in sourceDisplayClassVariables)
            {
                var variable = pair.Value;
                var oldDisplayClassInstance = variable.DisplayClassInstance;

                // Note: we don't call ToOtherMethod in the local case because doing so would produce
                // a new LocalSymbol that would not be ReferenceEquals to the one in this.LocalsForBinding.
                var oldDisplayClassInstanceFromLocal = oldDisplayClassInstance as DisplayClassInstanceFromLocal;
                var newDisplayClassInstance          = (oldDisplayClassInstanceFromLocal == null) ?
                                                       oldDisplayClassInstance.ToOtherMethod(this, this.TypeMap) :
                                                       new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[oldDisplayClassInstanceFromLocal.Local]);

                variable = variable.SubstituteFields(newDisplayClassInstance, this.TypeMap);
                displayClassVariables.Add(pair.Key, variable);
            }

            _displayClassVariables = displayClassVariables.ToImmutableDictionary();
            displayClassVariables.Free();
            localsMap.Free();

            _generateMethodBody = generateMethodBody;
        }
Example #4
0
 private TypeParameterChecker(ImmutableArray <TypeParameterSymbol> acceptableTypeParameters)
     : base(acceptableTypeParameters.As <ITypeParameterSymbol>())
 {
 }
Example #5
0
 private TypeParameterChecker(ImmutableArray<TypeParameterSymbol> acceptableTypeParameters)
     : base(acceptableTypeParameters.As<ITypeParameterSymbol>())
 {
 }
Example #6
0
        internal EEMethodSymbol(
            EENamedTypeSymbol container,
            string name,
            Location location,
            MethodSymbol sourceMethod,
            ImmutableArray<LocalSymbol> sourceLocals,
            ImmutableArray<LocalSymbol> sourceLocalsForBinding,
            ImmutableDictionary<string, DisplayClassVariable> sourceDisplayClassVariables,
            GenerateMethodBody generateMethodBody)
        {
            Debug.Assert(sourceMethod.IsDefinition);
            Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition);
            Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod));

            _container = container;
            _name = name;
            _locations = ImmutableArray.Create(location);

            // What we want is to map all original type parameters to the corresponding new type parameters
            // (since the old ones have the wrong owners).  Unfortunately, we have a circular dependency:
            //   1) Each new type parameter requires the entire map in order to be able to construct its constraint list.
            //   2) The map cannot be constructed until all new type parameters exist.
            // Our solution is to pass each new type parameter a lazy reference to the type map.  We then 
            // initialize the map as soon as the new type parameters are available - and before they are 
            // handed out - so that there is never a period where they can require the type map and find
            // it uninitialized.

            var sourceMethodTypeParameters = sourceMethod.TypeParameters;
            var allSourceTypeParameters = container.SourceTypeParameters.Concat(sourceMethodTypeParameters);

            var getTypeMap = new Func<TypeMap>(() => this.TypeMap);
            _typeParameters = sourceMethodTypeParameters.SelectAsArray(
                (tp, i, arg) => (TypeParameterSymbol)new EETypeParameterSymbol(this, tp, i, getTypeMap),
                (object)null);
            _allTypeParameters = container.TypeParameters.Concat(_typeParameters);
            this.TypeMap = new TypeMap(allSourceTypeParameters, _allTypeParameters);

            EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);

            var substitutedSourceType = container.SubstitutedSourceType;
            this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType);
            if (sourceMethod.Arity > 0)
            {
                this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As<TypeSymbol>());
            }
            TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters);

            // Create a map from original parameter to target parameter.
            var parameterBuilder = ArrayBuilder<ParameterSymbol>.GetInstance();

            var substitutedSourceThisParameter = this.SubstitutedSourceMethod.ThisParameter;
            var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null;
            if (substitutedSourceHasThisParameter)
            {
                _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter);
                Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType);
                parameterBuilder.Add(_thisParameter);
            }

            var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0);
            foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters)
            {
                var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset;
                Debug.Assert(ordinal == parameterBuilder.Count);
                var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter);
                parameterBuilder.Add(parameter);
            }

            _parameters = parameterBuilder.ToImmutableAndFree();

            var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            var localsMap = PooledDictionary<LocalSymbol, LocalSymbol>.GetInstance();
            foreach (var sourceLocal in sourceLocals)
            {
                var local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                localsMap.Add(sourceLocal, local);
                localsBuilder.Add(local);
            }
            this.Locals = localsBuilder.ToImmutableAndFree();
            localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            foreach (var sourceLocal in sourceLocalsForBinding)
            {
                LocalSymbol local;
                if (!localsMap.TryGetValue(sourceLocal, out local))
                {
                    local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                    localsMap.Add(sourceLocal, local);
                }
                localsBuilder.Add(local);
            }
            this.LocalsForBinding = localsBuilder.ToImmutableAndFree();

            // Create a map from variable name to display class field.
            var displayClassVariables = PooledDictionary<string, DisplayClassVariable>.GetInstance();
            foreach (var pair in sourceDisplayClassVariables)
            {
                var variable = pair.Value;
                var displayClassInstanceFromLocal = variable.DisplayClassInstance as DisplayClassInstanceFromLocal;
                var displayClassInstance = (displayClassInstanceFromLocal == null) ?
                    (DisplayClassInstance)new DisplayClassInstanceFromThis(_parameters[0]) :
                    new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[displayClassInstanceFromLocal.Local]);
                variable = variable.SubstituteFields(displayClassInstance, this.TypeMap);
                displayClassVariables.Add(pair.Key, variable);
            }

            _displayClassVariables = displayClassVariables.ToImmutableDictionary();
            displayClassVariables.Free();
            localsMap.Free();

            _generateMethodBody = generateMethodBody;
        }
Example #7
0
 public TargetList(string sql, ImmutableArray <ResTarget> targets)
     : base(sql, targets.As <SqlNode>())
 {
     this.Targets = targets;
 }
Example #8
0
 public SqlArgumentList(string sql, ImmutableArray <SqlArgument> arguments)
     : base(sql, arguments.As <SqlNode>())
 {
     this.Arguments = arguments;
 }