internal SynthesizedAttributeData GetVoStructAttributeData()
        {
            var syntax               = ((CSharpSyntaxNode)declaration.SyntaxReferences.FirstOrDefault()?.GetSyntax());
            var attributeType        = DeclaringCompilation.VOStructAttributeType();
            var int32type            = DeclaringCompilation.GetSpecialType(SpecialType.System_Int32);
            var attributeConstructor = attributeType.GetMembers(".ctor").FirstOrDefault() as MethodSymbol;
            var constructorArguments = ArrayBuilder <TypedConstant> .GetInstance();

            constructorArguments.Add(new TypedConstant(int32type, TypedConstantKind.Primitive, VoStructSize));
            constructorArguments.Add(new TypedConstant(int32type, TypedConstantKind.Primitive, VoStructElementSize));
            return(new SynthesizedAttributeData(attributeConstructor, constructorArguments.ToImmutableAndFree(), ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty));
        }
Example #2
0
        /// <summary>
        /// Emits conversion to <c>System.DateTime</c>.
        /// </summary>
        /// <param name="from">Value on stack to be converted.</param>
        private void EmitConvertToDateTime(TypeSymbol from)
        {
            // PhpValue
            EmitConvertToPhpValue(from, 0);

            // Convert.ToDateTime( STACK ) : DateTime
            var datetime = DeclaringCompilation.GetSpecialType(SpecialType.System_DateTime);
            var method   = CoreTypes.Convert.Method("ToDateTime", CoreTypes.PhpValue);

            EmitCall(ILOpCode.Call, method)
            .Expect(datetime);
        }
        internal override IEnumerable <AttributeData> GetCustomAttributesToEmit(CommonModuleCompilationState compilationState)
        {
            // [param]
            if (IsParams)
            {
                yield return(new SynthesizedAttributeData(
                                 (MethodSymbol)DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_ParamArrayAttribute__ctor),
                                 ImmutableArray <TypedConstant> .Empty, ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty));
            }

            // [NotNull]
            if (IsNotNull && Type.IsReferenceType)
            {
                yield return(new SynthesizedAttributeData(
                                 DeclaringCompilation.CoreMethods.Ctors.NotNullAttribute,
                                 ImmutableArray <TypedConstant> .Empty, ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty));
            }

            // [DefaultValue]
            if (this.Initializer is BoundArrayEx arr)
            {
                var typeParameter   = new KeyValuePair <string, TypedConstant>("Type", new TypedConstant(DeclaringCompilation.CoreTypes.DefaultValueType.Symbol, TypedConstantKind.Enum, 1 /*PhpArray*/));
                var namedparameters = ImmutableArray.Create(typeParameter);

                if (arr.Items.Length != 0)
                {
                    try
                    {
                        var byteSymbol      = DeclaringCompilation.GetSpecialType(SpecialType.System_Byte);
                        var serializedValue = Encoding.UTF8.GetBytes(arr.PhpSerializeOrThrow());
                        var p = new KeyValuePair <string, TypedConstant>(
                            "SerializedValue",
                            new TypedConstant(DeclaringCompilation.CreateArrayTypeSymbol(byteSymbol), serializedValue.Select(DeclaringCompilation.CreateTypedConstant).AsImmutable()));

                        namedparameters = namedparameters.Add(p);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException($"Cannot construct serialized parameter default value. Routine '{Routine.Name}' in {Routine.ContainingFile.RelativeFilePath}, {ex.Message}.", ex);
                    }
                }

                yield return(new SynthesizedAttributeData(
                                 DeclaringCompilation.CoreMethods.Ctors.DefaultValueAttribute,
                                 ImmutableArray <TypedConstant> .Empty, namedparameters));
            }

            //
            yield break;
        }
        internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
        {
            // TODO: HHVM TypeHint

            //
            if ((IsConst || IsReadOnly) && Initializer != null)
            {
                // resolved type symbol if possible
                if (Initializer.ResultType != null)
                {
                    return(Initializer.ResultType);
                }

                // resolved value type if possible
                var cvalue = Initializer.ConstantValue;
                if (cvalue.HasValue)
                {
                    var specialType = (cvalue.Value != null)
                        ? cvalue.ToConstantValueOrNull()?.SpecialType
                        : SpecialType.System_Object;    // NULL

                    if (specialType.HasValue && specialType != SpecialType.None)
                    {
                        return(DeclaringCompilation.GetSpecialType(specialType.Value));
                    }
                }

                //
                //return DeclaringCompilation.GetTypeFromTypeRef(typectx, Initializer.TypeRefMask);
            }

            // PHPDoc @var type
            if ((DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.FieldTypes) != 0)
            {
                var vartag = FindPhpDocVarTag();
                if (vartag != null && vartag.TypeNamesArray.Length != 0)
                {
                    var dummyctx = TypeRefFactory.CreateTypeRefContext(_containingType);
                    var tmask    = PHPDoc.GetTypeMask(dummyctx, vartag.TypeNamesArray, NameUtils.GetNamingContext(_containingType.Syntax));
                    return(DeclaringCompilation.GetTypeFromTypeRef(dummyctx, tmask));
                }
            }

            // default
            return(DeclaringCompilation.CoreTypes.PhpValue);
        }
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
        {
            base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

            if (this.HasUnmanagedTypeConstraint)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsUnmanagedAttribute(this));
            }

            byte nullableAttributeValue = NullableAnnotationExtensions.ObliviousAttributeValue;

            if (this.HasReferenceTypeConstraint)
            {
                switch (this.ReferenceTypeConstraintIsNullable)
                {
                case true:
                    nullableAttributeValue = NullableAnnotationExtensions.AnnotatedAttributeValue;
                    break;

                case false:
                    nullableAttributeValue = NullableAnnotationExtensions.NotAnnotatedAttributeValue;
                    break;
                }
            }
            else if (this.HasNotNullConstraint)
            {
                nullableAttributeValue = NullableAnnotationExtensions.NotAnnotatedAttributeValue;
            }
            else if (!this.HasValueTypeConstraint && this.ConstraintTypesNoUseSiteDiagnostics.IsEmpty && this.IsNotNullableIfReferenceType == false)
            {
                nullableAttributeValue = NullableAnnotationExtensions.AnnotatedAttributeValue;
            }

            if (nullableAttributeValue != NullableAnnotationExtensions.ObliviousAttributeValue)
            {
                NamedTypeSymbol byteType = DeclaringCompilation.GetSpecialType(SpecialType.System_Byte);
                Debug.Assert((object)byteType != null);

                AddSynthesizedAttribute(
                    ref attributes,
                    moduleBuilder.SynthesizeNullableAttribute(WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte,
                                                              ImmutableArray.Create(new TypedConstant(byteType, TypedConstantKind.Primitive,
                                                                                                      nullableAttributeValue))));
            }
        }
Example #6
0
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
        {
            base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

            if (this.HasUnmanagedTypeConstraint)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsUnmanagedAttribute(this));
            }

            if (this.HasReferenceTypeConstraint && this.ReferenceTypeConstraintIsNullable != null)
            {
                NamedTypeSymbol byteType = DeclaringCompilation.GetSpecialType(SpecialType.System_Byte);
                Debug.Assert((object)byteType != null);

                AddSynthesizedAttribute(
                    ref attributes,
                    moduleBuilder.SynthesizeNullableAttribute(WellKnownMember.System_Runtime_CompilerServices_NullableAttribute__ctorByte,
                                                              ImmutableArray.Create(new TypedConstant(byteType, TypedConstantKind.Primitive,
                                                                                                      (byte)(this.ReferenceTypeConstraintIsNullable == true ?
                                                                                                             NullableAnnotation.Annotated :
                                                                                                             NullableAnnotation.NotAnnotated)))));
            }
        }
        void EmitDisposable(Emit.PEModuleBuilder module, DiagnosticBag diagnostics)
        {
            var __destruct = TryGetDestruct();

            if (__destruct == null ||
                IsAlreadyImplemented(__destruct) ||
                IsAlreadyImplemented(DeclaringCompilation.GetSpecialType(SpecialType.System_IDisposable)))
            {
                // already implemented in a base class
                return;
            }

            //
            // IDisposable.Dispose()
            //
            var dispose = new SynthesizedMethodSymbol(this, "IDisposable.Dispose", false, true, DeclaringCompilation.GetSpecialType(SpecialType.System_Void), isfinal: true)
            {
                ExplicitOverride = (MethodSymbol)DeclaringCompilation.GetSpecialTypeMember(SpecialMember.System_IDisposable__Dispose),
                ForwardedCall    = __destruct,
            };

            module.SetMethodBody(dispose, MethodGenerator.GenerateMethodBody(module, dispose, il =>
            {
                var thisPlace = new ArgPlace(this, 0);
                var ctxPlace  = new FieldPlace(thisPlace, this.ContextStore, module);
                var cg        = new CodeGenerator(il, module, diagnostics, module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace)
                {
                    CallerType = this,
                };

                // private bool <>b_disposed;
                var disposedField = cg.Module.SynthesizedManager.GetOrCreateSynthesizedField(this, DeclaringCompilation.CoreTypes.Boolean, WellKnownPchpNames.SynthesizedDisposedFieldName, Accessibility.Private, false, false, false);
                var disposedPlace = new FieldPlace(thisPlace, disposedField, cg.Module);

                // if (<>b_disposed) return;
                var lblContinue = new object();
                disposedPlace.EmitLoad(cg.Builder);
                cg.Builder.EmitBranch(ILOpCode.Brfalse, lblContinue);
                cg.EmitRet(DeclaringCompilation.CoreTypes.Void);
                cg.Builder.MarkLabel(lblContinue);

                // <>b_disposed = true;
                disposedPlace.EmitStorePrepare(cg.Builder);
                cg.Builder.EmitBoolConstant(true);
                disposedPlace.EmitStore(cg.Builder);

                // __destruct()
                cg.EmitPop(cg.EmitForwardCall(__destruct, dispose, callvirt: true));

                // .ret
                cg.EmitRet(DeclaringCompilation.GetSpecialType(SpecialType.System_Void));
            }, null, diagnostics, false));

            module.SynthesizedManager.AddMethod(this, dispose);

            ////
            //// Finalize()
            ////
            //var finalize = new SynthesizedFinalizeSymbol(this)
            //{
            //    ForwardedCall = dispose,
            //};

            //Debug.Assert(finalize.OverriddenMethod != null);

            //module.SetMethodBody(finalize, MethodGenerator.GenerateMethodBody(module, finalize, il =>
            //{
            //    var thisPlace = new ArgPlace(this, 0);
            //    var ctxPlace = new FieldPlace(thisPlace, this.ContextStore, module);
            //    var cg = new CodeGenerator(il, module, diagnostics, module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace)
            //    {
            //        CallerType = this,
            //    };

            //    //
            //    cg.Builder.OpenLocalScope(ScopeType.TryCatchFinally);
            //    // try {
            //    cg.Builder.OpenLocalScope(ScopeType.Try);

            //    // Dispose()
            //    cg.EmitPop(cg.EmitForwardCall(dispose, finalize, callvirt: false));
            //    //if (cg.EmitPdbSequencePoints) cg.Builder.EmitOpCode(ILOpCode.Nop);

            //    // }
            //    cg.Builder.CloseLocalScope();
            //    // finally {
            //    cg.Builder.OpenLocalScope(ScopeType.Finally);

            //    // base.Finalize()
            //    thisPlace.EmitLoad(cg.Builder);
            //    cg.EmitCall(ILOpCode.Call, finalize.ExplicitOverride);
            //    //if (cg.EmitPdbSequencePoints) cg.Builder.EmitOpCode(ILOpCode.Nop);

            //    // }
            //    cg.Builder.CloseLocalScope();
            //    cg.Builder.CloseLocalScope();

            //    // .ret
            //    cg.EmitRet(DeclaringCompilation.GetSpecialType(SpecialType.System_Void));

            //}, null, diagnostics, false));

            //module.SynthesizedManager.AddMethod(this, finalize);
        }