Beispiel #1
0
 public static bool TryParseSourceMethodNameFromGeneratedName(string generatedName, GeneratedNameKind requiredKind, out string methodName) => Impl.TryParseSourceMethodNameFromGeneratedName(generatedName, requiredKind, out methodName);
Beispiel #2
0
 public static bool TryParseLocalFunctionNameFromGeneratedName(string generatedName, out string localFunctionName) =>
 Impl.TryParseLocalFunctionNameFromGeneratedName(generatedName, out localFunctionName);
Beispiel #3
0
 public static GeneratedNameKind GetKind(string name) => Impl.GetKind(name);
Beispiel #4
0
 public static bool TryParseGeneratedName(
     string name,
     out GeneratedNameKind kind,
     out int openBracketOffset,
     out int closeBracketOffset) => Impl.TryParseGeneratedName(name, out kind, out openBracketOffset, out closeBracketOffset);
Beispiel #5
0
 public string MakeTypeName()
 {
     return(GeneratedNames.MakeDynamicCallSiteDelegateName(_byRefs, _returnsVoid, _generation));
 }
Beispiel #6
0
 public static bool IsGeneratedMemberName(string memberName) => Impl.IsGeneratedMemberName(memberName);
Beispiel #7
0
            internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr)
            {
                this.Manager           = manager;
                this.TypeDescriptorKey = typeDescr.Key;
                this.smallestLocation  = typeDescr.Location;

                // Will be set when the type's metadata is ready to be emitted,
                // <anonymous-type>.Name will throw exception if requested
                // before that moment.
                this.nameAndIndex = null;

                int fieldsCount = typeDescr.Fields.Length;

                // members
                Symbol[] members     = new Symbol[fieldsCount * 3 + 1];
                int      memberIndex = 0;

                // The array storing property symbols to be used in
                // generation of constructor and other methods
                if (fieldsCount > 0)
                {
                    AnonymousTypePropertySymbol[] propertiesArray     = new AnonymousTypePropertySymbol[fieldsCount];
                    TypeParameterSymbol[]         typeParametersArray = new TypeParameterSymbol[fieldsCount];

                    // Process fields
                    for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++)
                    {
                        AnonymousTypeField field = typeDescr.Fields[fieldIndex];

                        // Add a type parameter
                        AnonymousTypeParameterSymbol typeParameter =
                            new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name));
                        typeParametersArray[fieldIndex] = typeParameter;

                        // Add a property
                        AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, typeParameter);
                        propertiesArray[fieldIndex] = property;

                        // Property related symbols
                        members[memberIndex++] = property;
                        members[memberIndex++] = property.BackingField;
                        members[memberIndex++] = property.GetMethod;
                    }

                    this.typeParameters = typeParametersArray.AsImmutable();
                    this.Properties     = propertiesArray.AsImmutable();
                }
                else
                {
                    this.typeParameters = ImmutableArray <TypeParameterSymbol> .Empty;
                    this.Properties     = ImmutableArray <AnonymousTypePropertySymbol> .Empty;
                }

                // Add a constructor
                members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties);
                this.members           = members.AsImmutable();

                Debug.Assert(memberIndex == this.members.Length);

                // fill nameToSymbols map
                foreach (var symbol in this.members)
                {
                    this.nameToSymbols.Add(symbol.Name, symbol);
                }

                // special members: Equals, GetHashCode, ToString
                MethodSymbol[] specialMembers = new MethodSymbol[3];
                specialMembers[0]   = new AnonymousTypeEqualsMethodSymbol(this);
                specialMembers[1]   = new AnonymousTypeGetHashCodeMethodSymbol(this);
                specialMembers[2]   = new AnonymousTypeToStringMethodSymbol(this);
                this.SpecialMembers = specialMembers.AsImmutable();
            }
Beispiel #8
0
        public void AssignTemplatesNamesAndCompile(MethodCompiler compiler, PEModuleBuilder moduleBeingBuilt, BindingDiagnosticBag diagnostics)
        {
            // Ensure all previous anonymous type templates are included so the
            // types are available for subsequent edit and continue generations.
            foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes())
            {
                var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Fields, f => f.Name);
                this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key));
            }

            // Get all anonymous types owned by this manager
            var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance();

            GetCreatedAnonymousTypeTemplates(builder);

            // If the collection is not sealed yet we should assign
            // new indexes to the created anonymous type templates
            if (!this.AreTemplatesSealed)
            {
                // If we are emitting .NET module, include module's name into type's name to ensure
                // uniqueness across added modules.
                string moduleId;

                if (moduleBeingBuilt.OutputKind == OutputKind.NetModule)
                {
                    moduleId = moduleBeingBuilt.Name;

                    string extension = OutputKind.NetModule.GetDefaultExtension();

                    if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase))
                    {
                        moduleId = moduleId.Substring(0, moduleId.Length - extension.Length);
                    }

                    moduleId = MetadataHelpers.MangleForTypeNameIfNeeded(moduleId);
                }
                else
                {
                    moduleId = string.Empty;
                }

                int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex();
                foreach (var template in builder)
                {
                    string name;
                    int    index;
                    if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index))
                    {
                        index = nextIndex++;
                        name  = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId);
                    }
                    // normally it should only happen once, but in case there is a race
                    // NameAndIndex.set has an assert which guarantees that the
                    // template name provided is the same as the one already assigned
                    template.NameAndIndex = new NameAndIndex(name, index);
                }

                this.SealTemplates();
            }

            if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics))
            {
                // Process all the templates
                foreach (var template in builder)
                {
                    foreach (var method in template.SpecialMembers)
                    {
                        moduleBeingBuilt.AddSynthesizedDefinition(template, method.GetCciAdapter());
                    }

                    compiler.Visit(template, null);
                }
            }

            builder.Free();

            var synthesizedDelegates = ArrayBuilder <SynthesizedDelegateSymbol> .GetInstance();

            GetCreatedSynthesizedDelegates(synthesizedDelegates);
            foreach (var synthesizedDelegate in synthesizedDelegates)
            {
                compiler.Visit(synthesizedDelegate, null);
            }
            synthesizedDelegates.Free();
        }
 public SynthesizedDelegateKey(int parameterCount, RefKindVector byRefs, bool returnsVoid, int generation)
 {
     Name           = GeneratedNames.MakeSynthesizedDelegateName(byRefs, returnsVoid, generation);
     ParameterCount = parameterCount;
     TypeDescriptor = default;
 }
            internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr)
            {
                this.Manager           = manager;
                this.TypeDescriptorKey = typeDescr.Key;
                _smallestLocation      = typeDescr.Location;

                // Will be set when the type's metadata is ready to be emitted,
                // <anonymous-type>.Name will throw exception if requested
                // before that moment.
                _nameAndIndex = null;

                int fieldsCount  = typeDescr.Fields.Length;
                int membersCount = fieldsCount * 3 + 1;

                // members
                var membersBuilder = ArrayBuilder <Symbol> .GetInstance(membersCount);

                var propertiesBuilder = ArrayBuilder <AnonymousTypePropertySymbol> .GetInstance(fieldsCount);

                var typeParametersBuilder = ArrayBuilder <TypeParameterSymbol> .GetInstance(fieldsCount);

                // Process fields
                for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++)
                {
                    AnonymousTypeField field = typeDescr.Fields[fieldIndex];

                    // Add a type parameter
                    AnonymousTypeParameterSymbol typeParameter =
                        new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name));
                    typeParametersBuilder.Add(typeParameter);

                    // Add a property
                    AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeWithAnnotations.Create(typeParameter), fieldIndex);
                    propertiesBuilder.Add(property);

                    // Property related symbols
                    membersBuilder.Add(property);
                    membersBuilder.Add(property.BackingField);
                    membersBuilder.Add(property.GetMethod);
                }

                _typeParameters = typeParametersBuilder.ToImmutableAndFree();
                this.Properties = propertiesBuilder.ToImmutableAndFree();

                // Add a constructor
                membersBuilder.Add(new AnonymousTypeConstructorSymbol(this, this.Properties));
                _members = membersBuilder.ToImmutableAndFree();
                Debug.Assert(membersCount == _members.Length);

                // fill nameToSymbols map
                foreach (var symbol in _members)
                {
                    _nameToSymbols.Add(symbol.Name, symbol);
                }

                // special members: Equals, GetHashCode, ToString
                this.SpecialMembers = ImmutableArray.Create <MethodSymbol>(
                    new AnonymousTypeEqualsMethodSymbol(this),
                    new AnonymousTypeGetHashCodeMethodSymbol(this),
                    new AnonymousTypeToStringMethodSymbol(this));
            }
Beispiel #11
0
        /// <summary>
        /// Resets numbering in anonymous type names and compiles the
        /// anonymous type methods. Also seals the collection of templates.
        /// </summary>
        public void AssignTemplatesNamesAndCompile(MethodCompiler compiler, PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics)
        {
            // Ensure all previous anonymous type templates are included so the
            // types are available for subsequent edit and continue generations.
            foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes())
            {
                var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, f => f);
                this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key));
            }

            // Get all anonymous types owned by this manager
            var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance();

            var anonymousTypes = lazyAnonymousTypeTemplates;

            if (anonymousTypes != null)
            {
                foreach (var template in anonymousTypes.Values)
                {
                    // NOTE: in interactive scenarios the cache may contain templates
                    //       from other compilation, those should be discarded here
                    if (ReferenceEquals(template.Manager, this))
                    {
                        builder.Add(template);
                    }
                }
            }

            // If the collection is not sealed yet we should assign
            // new indexes to the created anonymous type templates
            if (this.anonymousTypeTemplatesIsSealed != ThreeState.True)
            {
                // Sort type templates using smallest location
                builder.Sort(new AnonymousTypeComparer(this.Compilation));

                // If we are emitting .NET module, include module's name into type's name to ensure
                // uniqueness across added modules.
                string moduleId;

                if (moduleBeingBuilt.OutputKind == OutputKind.NetModule)
                {
                    moduleId = moduleBeingBuilt.Name;

                    string extension = OutputKind.NetModule.GetDefaultExtension();

                    if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase))
                    {
                        moduleId = moduleId.Substring(0, moduleId.Length - extension.Length);
                    }

                    moduleId = moduleId.Replace('.', '_');
                }
                else
                {
                    moduleId = string.Empty;
                }

                int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex();
                foreach (var template in builder)
                {
                    string name;
                    int    index;
                    if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index))
                    {
                        index = nextIndex++;
                        name  = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId);
                    }
                    // normally it should only happen once, but in case there is a race
                    // NameAndIndex.set has an assert which guarantees that the
                    // template name provided is the same as the one already assigned
                    template.NameAndIndex = new NameAndIndex(name, index);
                }

                this.anonymousTypeTemplatesIsSealed = ThreeState.True;
            }

            if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics))
            {
                // Process all the templates
                foreach (var template in builder)
                {
                    foreach (var method in template.SpecialMembers)
                    {
                        moduleBeingBuilt.AddSynthesizedDefinition(template, method);
                    }

                    compiler.Visit(template, null);
                }
            }

            builder.Free();

            var delegates = lazySynthesizedDelegates;

            if (delegates != null)
            {
                foreach (var template in delegates.Values)
                {
                    // NOTE: in interactive scenarios the cache may contain templates
                    //       from other compilation, those should be discarded here
                    if (ReferenceEquals(template.Manager, this))
                    {
                        compiler.Visit(template.Delegate, null);
                    }
                }
            }
        }
Beispiel #12
0
 public string MakeTypeName()
 {
     return(GeneratedNames.MakeSynthesizedDelegateName(_byRefs, _returnsVoid, _generation));
 }
Beispiel #13
0
        private ImmutableArray <ParameterSymbol> MakeParameters(
            CSharpCompilation compilation,
            UnboundLambda unboundLambda,
            ImmutableArray <TypeWithAnnotations> parameterTypes,
            ImmutableArray <RefKind> parameterRefKinds,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(parameterTypes.Length == parameterRefKinds.Length);

            if (!unboundLambda.HasSignature || unboundLambda.ParameterCount == 0)
            {
                // The parameters may be omitted in source, but they are still present on the symbol.
                return(parameterTypes.SelectAsArray((type, ordinal, arg) =>
                                                    SynthesizedParameterSymbol.Create(
                                                        arg.owner,
                                                        type,
                                                        ordinal,
                                                        arg.refKinds[ordinal],
                                                        GeneratedNames.LambdaCopyParameterName(ordinal)),     // Make sure nothing binds to this.
                                                    (owner: this, refKinds: parameterRefKinds)));
            }

            var builder = ArrayBuilder <ParameterSymbol> .GetInstance(unboundLambda.ParameterCount);

            var hasExplicitlyTypedParameterList = unboundLambda.HasExplicitlyTypedParameterList;
            var numDelegateParameters           = parameterTypes.Length;

            for (int p = 0; p < unboundLambda.ParameterCount; ++p)
            {
                // If there are no types given in the lambda then used the delegate type.
                // If the lambda is typed then the types probably match the delegate types;
                // if they do not, use the lambda types for binding. Either way, if we
                // can, then we use the lambda types. (Whatever you do, do not use the names
                // in the delegate parameters; they are not in scope!)

                TypeWithAnnotations type;
                RefKind             refKind;
                if (hasExplicitlyTypedParameterList)
                {
                    type    = unboundLambda.ParameterTypeWithAnnotations(p);
                    refKind = unboundLambda.RefKind(p);
                }
                else if (p < numDelegateParameters)
                {
                    type    = parameterTypes[p];
                    refKind = parameterRefKinds[p];
                }
                else
                {
                    type    = TypeWithAnnotations.Create(new ExtendedErrorTypeSymbol(compilation, name: string.Empty, arity: 0, errorInfo: null));
                    refKind = RefKind.None;
                }

                var name      = unboundLambda.ParameterName(p);
                var location  = unboundLambda.ParameterLocation(p);
                var locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create <Location>(location);
                var parameter = new SourceSimpleParameterSymbol(this, type, p, refKind, name, locations);

                builder.Add(parameter);
            }

            var result = builder.ToImmutableAndFree();

            return(result);
        }