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)); }
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); }
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)); }
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)); }