예제 #1
0
        private JsExpression CreateInitEnumCall(JsEnum type, string ctorName)
        {
            var values = new List <JsObjectLiteralProperty>();

            foreach (var v in type.CSharpTypeDefinition.Fields)
            {
                if (v.ConstantValue != null)
                {
                    var sem = _metadataImporter.GetFieldSemantics(v);
                    if (sem.Type == FieldScriptSemantics.ImplType.Field)
                    {
                        values.Add(new JsObjectLiteralProperty(sem.Name, JsExpression.Number(Convert.ToDouble(v.ConstantValue))));
                    }
                    else if (sem.Type == FieldScriptSemantics.ImplType.Constant && sem.Name != null)
                    {
                        values.Add(new JsObjectLiteralProperty(sem.Name, sem.Value is string?JsExpression.String((string)sem.Value) : JsExpression.Number(Convert.ToDouble(sem.Value))));
                    }
                }
                else
                {
                    _errorReporter.Region = v.Region;
                    _errorReporter.InternalError("Enum field " + v.FullName + " is not constant.");
                }
            }

            var args = new List <JsExpression> {
                JsExpression.Identifier(ctorName), _linker.CurrentAssemblyExpression, JsExpression.ObjectLiteral(values)
            };

            if (MetadataUtils.IsNamedValues(type.CSharpTypeDefinition, _attributeStore))
            {
                args.Add(JsExpression.True);
            }
            return(JsExpression.Invocation(JsExpression.Member(_systemScript, InitEnum), args));
        }
예제 #2
0
        private JsExpression GetFieldHashCode(IField field)
        {
            var impl = _metadataImporter.GetFieldSemantics(field);

            if (impl.Type != FieldScriptSemantics.ImplType.Field)
            {
                return(null);
            }

            IType        type          = NullableType.GetUnderlyingType(field.Type);
            bool         needNullCheck = field.Type.IsReferenceType != false || field.Type.IsKnownType(KnownTypeCode.NullableOfT) || type.Kind == TypeKind.Enum && MetadataUtils.IsNamedValues(field.Type.GetDefinition(), _attributeStore);
            JsExpression member        = JsExpression.Member(JsExpression.This, impl.Name);

            JsExpression result = JsExpression.Invocation(JsExpression.Member(_systemScript, "getHashCode"), member);

            if (needNullCheck)
            {
                result = JsExpression.Conditional(member, result, JsExpression.Number(0));
            }

            if (type.Kind == TypeKind.Enum && !MetadataUtils.IsNamedValues(type.GetDefinition(), _attributeStore))
            {
                result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member;
            }
            else if (type is ITypeDefinition)
            {
                switch (((ITypeDefinition)type).KnownTypeCode)
                {
                case KnownTypeCode.Boolean:
                    result = JsExpression.Conditional(member, JsExpression.Number(1), JsExpression.Number(0));
                    break;

                case KnownTypeCode.Byte:
                case KnownTypeCode.SByte:
                case KnownTypeCode.Char:
                case KnownTypeCode.Int16:
                case KnownTypeCode.UInt16:
                case KnownTypeCode.Int32:
                case KnownTypeCode.UInt32:
                case KnownTypeCode.Int64:
                case KnownTypeCode.UInt64:
                case KnownTypeCode.Decimal:
                case KnownTypeCode.Single:
                case KnownTypeCode.Double:
                    result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member;
                    break;
                }
            }

            return(result);
        }
예제 #3
0
        private JsExpression GenerateFieldCompare(IField field, JsExpression o)
        {
            var impl = _metadataImporter.GetFieldSemantics(field);

            if (impl.Type != FieldScriptSemantics.ImplType.Field)
            {
                return(null);
            }

            bool simpleCompare = false;

            if (field.Type.Kind == TypeKind.Enum && !MetadataUtils.IsNamedValues(field.Type.GetDefinition(), _attributeStore))
            {
                simpleCompare = true;
            }
            if (field.Type is ITypeDefinition)
            {
                switch (((ITypeDefinition)field.Type).KnownTypeCode)
                {
                case KnownTypeCode.Boolean:
                case KnownTypeCode.Byte:
                case KnownTypeCode.SByte:
                case KnownTypeCode.Char:
                case KnownTypeCode.Int16:
                case KnownTypeCode.UInt16:
                case KnownTypeCode.Int32:
                case KnownTypeCode.UInt32:
                case KnownTypeCode.Int64:
                case KnownTypeCode.UInt64:
                case KnownTypeCode.Decimal:
                case KnownTypeCode.Single:
                case KnownTypeCode.Double:
                    simpleCompare = true;
                    break;
                }
            }

            var m1 = JsExpression.Member(JsExpression.This, impl.Name);
            var m2 = JsExpression.Member(o, impl.Name);

            return(simpleCompare ? (JsExpression)JsExpression.Same(m1, m2) : JsExpression.Invocation(JsExpression.Member(_systemScript, "equals"), m1, m2));
        }
예제 #4
0
        public JsExpression Default(IType type, IRuntimeContext context)
        {
            if (type.IsReferenceType == true || type.Kind == TypeKind.Dynamic || type.IsKnownType(KnownTypeCode.NullableOfT))
            {
                return(JsExpression.Null);
            }
            else if (type.Kind == TypeKind.Enum)
            {
                return(MetadataUtils.IsNamedValues(type.GetDefinition(), _attributeStore) ? JsExpression.Null : JsExpression.Number(0));
            }
            else if (type is ITypeDefinition)
            {
                switch (((ITypeDefinition)type).KnownTypeCode)
                {
                case KnownTypeCode.Boolean:
                    return(JsExpression.False);

                case KnownTypeCode.NullableOfT:
                    return(JsExpression.Null);

                case KnownTypeCode.DateTime:
                    return(JsExpression.New(CreateTypeReferenceExpression(KnownTypeReference.DateTime), JsExpression.Number(0)));

                case KnownTypeCode.Byte:
                case KnownTypeCode.SByte:
                case KnownTypeCode.Char:
                case KnownTypeCode.Int16:
                case KnownTypeCode.UInt16:
                case KnownTypeCode.Int32:
                case KnownTypeCode.UInt32:
                case KnownTypeCode.Int64:
                case KnownTypeCode.UInt64:
                case KnownTypeCode.Decimal:
                case KnownTypeCode.Single:
                case KnownTypeCode.Double:
                    return(JsExpression.Number(0));
                }
            }
            return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "getDefaultValue"), GetScriptType(type, TypeContext.GetScriptType, context)));
        }
        private JsExpression GetCastTarget(IType type, IRuntimeContext context)
        {
            var def = type.GetDefinition();

            if (type.Kind == TypeKind.Enum)
            {
                var underlying = MetadataUtils.IsNamedValues(def) ? _compilation.FindType(KnownTypeCode.String) : def.EnumUnderlyingType;
                return(CreateTypeReferenceExpression(underlying.GetDefinition()));
            }

            if (def != null)
            {
                if (MetadataUtils.IsSerializable(def) && string.IsNullOrEmpty(MetadataUtils.GetSerializableTypeCheckCode(def)))
                {
                    return(null);
                }
                if (!MetadataUtils.DoesTypeObeyTypeSystem(def))
                {
                    return(null);
                }
            }

            return(GetScriptType(type, TypeContext.GetScriptType, context));
        }