private static bool UntypedNullAwareIsPromotableTo(TypeUsage fromType, TypeUsage toType) { if (fromType == null) { // // We can implicitly promote null to any type except collection. // return(!Helper.IsCollectionType(toType.EdmType)); } else { return(TypeSemantics.IsPromotableTo(fromType, toType)); } }
private static string GetTypeUsageToken(TypeUsage type) { string result = null; // Dev10#537010: EntityCommand false positive cache hits caused by insufficient parameter type information in cache key // Ensure String types are correctly differentiated. if (ReferenceEquals(type, DbTypeMap.AnsiString)) { result = "AnsiString"; } else if (ReferenceEquals(type, DbTypeMap.AnsiStringFixedLength)) { result = "AnsiStringFixedLength"; } else if (ReferenceEquals(type, DbTypeMap.String)) { result = "String"; } else if (ReferenceEquals(type, DbTypeMap.StringFixedLength)) { result = "StringFixedLength"; } else if (ReferenceEquals(type, DbTypeMap.Xml)) { // Xml is currently mapped to (unicode, variable-length) string, so the TypeUsage // given to the provider is actually a String TypeUsage. Debug.Assert( TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String), "Update GetTypeUsageToken to return 'Xml' for Xml parameters"); result = "String"; } else if (TypeSemantics.IsEnumerationType(type)) { result = type.EdmType.FullName; } else { // String/Xml TypeUsages are the only DbType-derived TypeUsages that carry meaningful facets. // Otherwise, the primitive type name is a sufficient token (note that full name is not required // since model types always have the 'Edm' namespace). Debug.Assert(TypeSemantics.IsPrimitiveType(type), "EntityParameter TypeUsage not a primitive type?"); Debug.Assert( !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String), "String TypeUsage not derived from DbType.AnsiString, AnsiString, String, StringFixedLength or Xml?"); result = type.EdmType.Name; } return(result); }
internal static bool IsValidSortOpKeyType(TypeUsage typeUsage) { if (!TypeSemantics.IsRowType(typeUsage)) { return(TypeSemantics.IsOrderComparable(typeUsage)); } foreach (EdmMember property in ((RowType)typeUsage.EdmType).Properties) { if (!TypeHelpers.IsValidSortOpKeyType(property.TypeUsage)) { return(false); } } return(true); }
private static void RequireCompatibleType( DbExpression expression, TypeUsage requiredResultType, string argumentName, int argumentIndex) { if (!TypeSemantics.IsStructurallyEqualOrPromotableTo(expression.ResultType, requiredResultType)) { if (argumentIndex != -1) { argumentName = StringUtil.FormatIndex(argumentName, argumentIndex); } throw new ArgumentException(Strings.Cqt_ExpressionLink_TypeMismatch((object)expression.ResultType.ToString(), (object)requiredResultType.ToString()), argumentName); } }
internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape) : base(DbExpressionKind.Like, booleanResultType) { Debug.Assert(input != null, "DbLikeExpression argument cannot be null"); Debug.Assert(pattern != null, "DbLikeExpression pattern cannot be null"); Debug.Assert(escape != null, "DbLikeExpression escape cannot be null"); Debug.Assert(TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type"); this._argument = input; this._pattern = pattern; this._escape = escape; }
private static bool ValidateFunctionImportMappingResultTypeCompatibility( TypeUsage cSpaceMemberType, TypeUsage sSpaceMemberType) { TypeUsage typeUsage1 = sSpaceMemberType; TypeUsage typeUsage2 = FunctionImportMappingComposableHelper.ResolveTypeUsageForEnums(cSpaceMemberType); bool flag1 = TypeSemantics.IsStructurallyEqualOrPromotableTo(typeUsage1, typeUsage2); bool flag2 = TypeSemantics.IsStructurallyEqualOrPromotableTo(typeUsage2, typeUsage1); if (!flag1) { return(flag2); } return(true); }
internal DbExpression(DbExpressionKind kind, TypeUsage type) { CheckExpressionKind(kind); _kind = kind; Debug.Assert(type != null, string.Format(CultureInfo.InvariantCulture, "{0}.Type is null in DbExpression constructor", this.GetType().Name)); if (!TypeSemantics.IsNullable(type)) { type = type.ShallowCopy(new FacetValues { Nullable = true }); } Debug.Assert(type.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); this._type = type; }
internal static ProviderCommandInfo Create(Command command, System.Data.Entity.Core.Query.InternalTrees.Node node) { PhysicalProjectOp op = node.Op as PhysicalProjectOp; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(op != null, "Expected root Op to be a physical Project"); DbCommandTree commandTree = CTreeGenerator.Generate(command, node); DbQueryCommandTree queryCommandTree = commandTree as DbQueryCommandTree; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(queryCommandTree != null, "null query command tree"); CollectionType edmType = TypeHelpers.GetEdmType <CollectionType>(queryCommandTree.Query.ResultType); System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsRowType(edmType.TypeUsage), "command rowtype is not a record"); ProviderCommandInfoUtils.BuildOutputVarMap(op, edmType.TypeUsage); return(new ProviderCommandInfo(commandTree)); }
/// <summary> /// Determine whether the given CLR type is legal for an ObjectParameter or constant /// DbExpression. /// </summary> private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage) { EntityUtil.CheckArgumentNull(type, "type"); if (_rootContext.Perspective.TryGetTypeByName(TypeSystem.GetNonNullableType(type).FullName, false, // bIgnoreCase out typeUsage) && (TypeSemantics.IsScalarType(typeUsage))) { return(true); } typeUsage = null; return(false); }
internal MemberInformation( int ordinal, int?entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember) { this.Ordinal = ordinal; this.EntityKeyOrdinal = entityKeyOrdinal; this.Flags = flags; this.Member = member; this.IsServerGenerated = isServerGenerated; this.CheckIsNotNull = !TypeSemantics.IsNullable(member) && (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType); }
internal static TypeUsage ValidateRefFromKey( EntitySet entitySet, DbExpression keyValues, EntityType entityType) { ArgumentValidation.CheckEntitySet((EntitySetBase)entitySet, nameof(entitySet)); ArgumentValidation.CheckType((EdmType)entityType); if (!TypeSemantics.IsValidPolymorphicCast((EdmType)entitySet.ElementType, (EdmType)entityType)) { throw new ArgumentException(Strings.Cqt_Ref_PolymorphicArgRequired); } TypeUsage resultType = ArgumentValidation.CreateResultType((EdmType)TypeHelpers.CreateKeyRowType((EntityTypeBase)entitySet.ElementType)); ArgumentValidation.RequireCompatibleType(keyValues, resultType, nameof(keyValues)); return(ArgumentValidation.CreateReferenceResultType((EntityTypeBase)entityType)); }
internal DbComparisonExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpression left, DbExpression right) : base(kind, booleanResultType, left, right) { Debug.Assert(left != null, "DbComparisonExpression left cannot be null"); Debug.Assert(right != null, "DbComparisonExpression right cannot be null"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbComparisonExpression result type must be a Boolean type"); Debug.Assert( DbExpressionKind.Equals == kind || DbExpressionKind.LessThan == kind || DbExpressionKind.LessThanOrEquals == kind || DbExpressionKind.GreaterThan == kind || DbExpressionKind.GreaterThanOrEquals == kind || DbExpressionKind.NotEquals == kind, "Invalid DbExpressionKind used in DbComparisonExpression: " + Enum.GetName(typeof(DbExpressionKind), kind) ); }
internal DbQuantifierExpression( DbExpressionKind kind, TypeUsage booleanResultType, DbExpressionBinding input, DbExpression predicate) : base(kind, booleanResultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(predicate); Debug.Assert( TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression must have a Boolean result type"); Debug.Assert( TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression predicate must have a Boolean result type"); _input = input; _predicate = predicate; }
internal static TypeUsage RequireCollectionArguments <TExpressionType>( DbExpression left, DbExpression right) { if (!TypeSemantics.IsCollectionType(left.ResultType) || !TypeSemantics.IsCollectionType(right.ResultType)) { throw new ArgumentException(Strings.Cqt_Binary_CollectionsRequired((object)typeof(TExpressionType).Name)); } TypeUsage commonTypeUsage = TypeHelpers.GetCommonTypeUsage(left.ResultType, right.ResultType); if (commonTypeUsage == null) { throw new ArgumentException(Strings.Cqt_Binary_CollectionsRequired((object)typeof(TExpressionType).Name)); } return(commonTypeUsage); }
internal static bool IsRowTypeCaseOpWithNullability( CaseOp op, System.Data.Entity.Core.Query.InternalTrees.Node n, out bool thenClauseIsNull) { thenClauseIsNull = false; if (!TypeSemantics.IsRowType(op.Type) || n.Children.Count != 3 || (!n.Child1.Op.Type.EdmEquals((MetadataItem)op.Type) || !n.Child2.Op.Type.EdmEquals((MetadataItem)op.Type))) { return(false); } if (n.Child1.Op.OpType == OpType.Null) { thenClauseIsNull = true; return(true); } return(n.Child2.Op.OpType == OpType.Null); }
/// <summary> /// Determine whether the given CLR type is legal for an ObjectParameter or constant /// DbExpression. /// </summary> private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage) { DebugCheck.NotNull(type); if (_rootContext.Perspective.TryGetTypeByName( TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, // bIgnoreCase out typeUsage) && (TypeSemantics.IsScalarType(typeUsage))) { return(true); } typeUsage = null; return(false); }
internal DbExpression(DbExpressionKind kind, TypeUsage type, bool forceNullable = true) { CheckExpressionKind(kind); _kind = kind; DebugCheck.NotNull(type); if (forceNullable && !TypeSemantics.IsNullable(type)) { type = type.ShallowCopy( new FacetValues { Nullable = true }); } Debug.Assert(type.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); _type = type; }
public override DbExpression Visit(DbIsNullExpression expression) { EntityUtil.CheckArgumentNull(expression, "expression"); return(VisitUnary(expression, exp => { if (TypeSemantics.IsRowType(exp.ResultType)) { // return CqtBuilder.CreateIsNullExpressionAllowingRowTypeArgument(exp); } else { return CqtBuilder.IsNull(exp); } } )); }
internal MemberInformation(int ordinal, int?entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember) { Debug.Assert(entityKeyOrdinal.HasValue == (member.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType && (flags & PropagatorFlags.Key) == PropagatorFlags.Key), "key ordinal should only be provided if this is an entity key property"); this.Ordinal = ordinal; this.EntityKeyOrdinal = entityKeyOrdinal; this.Flags = flags; this.Member = member; this.IsServerGenerated = isServerGenerated; // in two cases, we must check that a member value is not null: // - where the type participates in an isnull condition, nullability constraints must be honored // - for complex types, mapping relies on nullability constraint // - in other cases, nullability does not impact round trippability so we don't check this.CheckIsNotNull = !TypeSemantics.IsNullable(member) && (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType); }
private void AssignTypeIds() { int num = 0; foreach (KeyValuePair <TypeUsage, TypeInfo> typeInfo in this.m_typeInfoMap) { if (typeInfo.Value.RootType.DiscriminatorMap != null) { EntityType edmType = (EntityType)typeInfo.Key.EdmType; typeInfo.Value.TypeId = typeInfo.Value.RootType.DiscriminatorMap.GetTypeId(edmType); } else if (typeInfo.Value.IsRootType && (TypeSemantics.IsEntityType(typeInfo.Key) || TypeSemantics.IsComplexType(typeInfo.Key))) { this.AssignRootTypeId(typeInfo.Value, string.Format((IFormatProvider)CultureInfo.InvariantCulture, "{0}X", (object)num)); ++num; } } }
private static bool IsValidRelationshipSpan( EntityType compareType, AssociationType associationType, AssociationEndMember fromEnd, AssociationEndMember toEnd) { if (associationType.IsForeignKey || RelationshipMultiplicity.One != toEnd.RelationshipMultiplicity && toEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) { return(false); } EntityType elementType = (EntityType)((RefType)fromEnd.TypeUsage.EdmType).ElementType; if (!ObjectSpanRewriter.EntityTypeEquals((EntityTypeBase)compareType, (EntityTypeBase)elementType) && !TypeSemantics.IsSubTypeOf((EdmType)compareType, (EdmType)elementType)) { return(TypeSemantics.IsSubTypeOf((EdmType)elementType, (EdmType)compareType)); } return(true); }
/// <summary> /// Resolves <paramref name="argTypes"/> against the list of function signatures. /// </summary> /// <returns>Funciton metadata</returns> internal static EdmFunction ResolveFunctionOverloads(IList <EdmFunction> functionsMetadata, IList <TypeUsage> argTypes, bool isGroupAggregateFunction, out bool isAmbiguous) { return(ResolveFunctionOverloads( functionsMetadata, argTypes, (edmFunction) => edmFunction.Parameters, (functionParameter) => functionParameter.TypeUsage, (functionParameter) => functionParameter.Mode, (argType) => TypeSemantics.FlattenType(argType), (paramType, argType) => TypeSemantics.FlattenType(paramType), (fromType, toType) => TypeSemantics.IsPromotableTo(fromType, toType), (fromType, toType) => TypeSemantics.IsStructurallyEqual(fromType, toType), isGroupAggregateFunction, out isAmbiguous)); }
private void CreateFlattenedRecordType(RootTypeInfo type) { bool flag = TypeSemantics.IsEntityType(type.Type) && type.ImmediateSubTypes.Count == 0; List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >(); HashSet <string> stringSet = new HashSet <string>(); int num = 0; foreach (PropertyRef propertyRef in type.PropertyRefList) { string key = (string)null; if (flag) { SimplePropertyRef simplePropertyRef = propertyRef as SimplePropertyRef; if (simplePropertyRef != null) { key = simplePropertyRef.Property.Name; } } if (key == null) { key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture); ++num; } while (stringSet.Contains(key)) { key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture); ++num; } TypeUsage propertyType = this.GetPropertyType(type, propertyRef); keyValuePairList.Add(new KeyValuePair <string, TypeUsage>(key, propertyType)); stringSet.Add(key); } type.FlattenedType = TypeHelpers.CreateRowType((IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList); IEnumerator <PropertyRef> enumerator = type.PropertyRefList.GetEnumerator(); foreach (EdmProperty property in type.FlattenedType.Properties) { if (!enumerator.MoveNext()) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?"); } type.AddPropertyMapping(enumerator.Current, property); } }
/// <summary> /// Recursively add any Row types to the list of types needing a sentinel. /// </summary> /// <param name="typesNeedingNullableSentinel"> </param> /// <param name="typeUsage"> </param> private static void AddTypeNeedingNullSentinel(HashSet <string> typesNeedingNullSentinel, TypeUsage typeUsage) { if (TypeSemantics.IsCollectionType(typeUsage)) { AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage)); } else { if (TypeSemantics.IsRowType(typeUsage) || TypeSemantics.IsComplexType(typeUsage)) { MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage); } foreach (EdmMember m in TypeHelpers.GetAllStructuralMembers(typeUsage)) { AddTypeNeedingNullSentinel(typesNeedingNullSentinel, m.TypeUsage); } } }
// // Type Semantics // /// <summary> /// Determines whether a given typeUsage is valid as OrderBy sort key /// </summary> /// <param name="typeUsage"> </param> /// <returns> </returns> internal static bool IsValidSortOpKeyType(TypeUsage typeUsage) { if (TypeSemantics.IsRowType(typeUsage)) { var rowType = (RowType)typeUsage.EdmType; foreach (var property in rowType.Properties) { if (!IsValidSortOpKeyType(property.TypeUsage)) { return(false); } } return(true); } else { return(TypeSemantics.IsOrderComparable(typeUsage)); } }
public override void Visit(CaseOp op, Node n) { VisitScalarOpDefault(op, n); Assert((n.Children.Count >= 3 && n.Children.Count % 2 == 1), "CaseOp: Expected odd number of arguments, and at least 3; found {0}", n.Children.Count); // Validate that each when statement is of type Boolean for (int i = 0; i < n.Children.Count - 1; i += 2) { Assert(TypeSemantics.IsBooleanType(n.Children[i].Op.Type), "Encountered a when node with a non-boolean return type"); } // Ensure that the then clauses, the else clause and the result type are all the same for (int i = 1; i < n.Children.Count - 1; i += 2) { AssertEqualTypes(n.Op.Type, n.Children[i].Op.Type); } AssertEqualTypes(n.Op.Type, n.Children[n.Children.Count - 1].Op.Type); }
internal static bool IsSetComparableOpType(TypeUsage typeUsage) { if (Helper.IsEntityType(typeUsage.EdmType) || Helper.IsPrimitiveType(typeUsage.EdmType) || (Helper.IsEnumType(typeUsage.EdmType) || Helper.IsRefType((GlobalItem)typeUsage.EdmType))) { return(true); } if (!TypeSemantics.IsRowType(typeUsage)) { return(false); } foreach (EdmMember property in ((RowType)typeUsage.EdmType).Properties) { if (!TypeHelpers.IsSetComparableOpType(property.TypeUsage)) { return(false); } } return(true); }
private DbExpression GenerateScalarResultMappingView( DbExpression storeFunctionInvoke) { DbExpression source = storeFunctionInvoke; CollectionType functionImportReturnType; MetadataHelper.TryGetFunctionImportReturnCollectionType(this.FunctionImport, 0, out functionImportReturnType); EdmProperty column = ((RowType)((CollectionType)source.ResultType.EdmType).TypeUsage.EdmType).Properties[0]; Func <DbExpression, DbExpression> scalarView = (Func <DbExpression, DbExpression>)(row => { DbPropertyExpression propertyExpression = row.Property(column); if (TypeSemantics.IsEqual(functionImportReturnType.TypeUsage, column.TypeUsage)) { return((DbExpression)propertyExpression); } return((DbExpression)propertyExpression.CastTo(functionImportReturnType.TypeUsage)); }); return((DbExpression)source.Select <DbExpression>((Func <DbExpression, DbExpression>)(row => scalarView(row)))); }
private static void AddTypeNeedingNullSentinel( HashSet <string> typesNeedingNullSentinel, TypeUsage typeUsage) { if (TypeSemantics.IsCollectionType(typeUsage)) { StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage)); } else { if (TypeSemantics.IsRowType(typeUsage) || TypeSemantics.IsComplexType(typeUsage)) { StructuredTypeNullabilityAnalyzer.MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage); } foreach (EdmMember structuralMember in (IEnumerable)TypeHelpers.GetAllStructuralMembers(typeUsage)) { StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, structuralMember.TypeUsage); } } }
internal static void ReportFunctionOverloadError( MethodExpr functionExpr, EdmFunction functionType, List <TypeUsage> argTypes) { string str = ""; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(functionType.Name).Append("("); for (int index = 0; index < argTypes.Count; ++index) { stringBuilder.Append(str); stringBuilder.Append(argTypes[index] != null ? argTypes[index].EdmType.FullName : "NULL"); str = ", "; } stringBuilder.Append(")"); Func <object, object, object, string> func = !TypeSemantics.IsAggregateFunction(functionType) ? (TypeHelpers.IsCanonicalFunction(functionType) ? new Func <object, object, object, string>(Strings.NoCanonicalFunctionOverloadMatch) : new Func <object, object, object, string>(Strings.NoFunctionOverloadMatch)) : (TypeHelpers.IsCanonicalFunction(functionType) ? new Func <object, object, object, string>(Strings.NoCanonicalAggrFunctionOverloadMatch) : new Func <object, object, object, string>(Strings.NoAggrFunctionOverloadMatch)); throw EntitySqlException.Create(functionExpr.ErrCtx.CommandText, func((object)functionType.NamespaceName, (object)functionType.Name, (object)stringBuilder.ToString()), functionExpr.ErrCtx.InputPosition, Strings.CtxFunction((object)functionType.Name), false, (Exception)null); }
public void Read(TagRepository rpa, CatalogReader catalog, BinaryReader reader) { m_semantics = (TypeSemantics)reader.ReadByte(); switch (m_semantics) { case TypeSemantics.Class: case TypeSemantics.Interface: case TypeSemantics.Struct: case TypeSemantics.Enum: case TypeSemantics.Delegate: break; default: throw new RpaLoadException("Invalid type semantics"); } m_typeName = catalog.GetTypeName(reader.ReadUInt32()); if (m_typeName.AssemblyName != catalog.AssemblyName) throw new Exception("Type definition outside of assembly"); m_numGenericParameters = m_typeName.NumGenericParameters; m_underlyingType = EnumUnderlyingType.NotEnum; if (m_semantics == TypeSemantics.Delegate) { this.ReadDelegate(rpa, catalog, reader); } else if (m_semantics == TypeSemantics.Enum) { this.ReadEnum(rpa, catalog, reader); } else { this.ReadClassDefinitions(rpa, catalog, reader); if (m_semantics == Clarity.Rpa.TypeSemantics.Class || m_semantics == Clarity.Rpa.TypeSemantics.Struct) this.ReadClassStatics(rpa, catalog, reader); } }
private void ProcessType(ITypeDefinition typeDefinition) { if (typeDefinition.Kind == TypeKind.Delegate) { ProcessDelegate(typeDefinition); return; } if (AttributeReader.HasAttribute<NonScriptableAttribute>(typeDefinition) || typeDefinition.DeclaringTypeDefinition != null && GetTypeSemantics(typeDefinition.DeclaringTypeDefinition).Type == TypeScriptSemantics.ImplType.NotUsableFromScript) { _typeSemantics[typeDefinition] = new TypeSemantics(TypeScriptSemantics.NotUsableFromScript(), false, false, false); return; } var scriptNameAttr = AttributeReader.ReadAttribute<ScriptNameAttribute>(typeDefinition); var importedAttr = AttributeReader.ReadAttribute<ImportedAttribute>(typeDefinition.Attributes); bool preserveName = importedAttr != null || AttributeReader.HasAttribute<PreserveNameAttribute>(typeDefinition); bool? includeGenericArguments = typeDefinition.TypeParameterCount > 0 ? MetadataUtils.ShouldGenericArgumentsBeIncluded(typeDefinition) : false; if (includeGenericArguments == null) { _errorReporter.Region = typeDefinition.Region; Message(Messages._7026, typeDefinition); includeGenericArguments = true; } if (AttributeReader.HasAttribute<ResourcesAttribute>(typeDefinition)) { if (!typeDefinition.IsStatic) { Message(Messages._7003, typeDefinition); } else if (typeDefinition.TypeParameterCount > 0) { Message(Messages._7004, typeDefinition); } else if (typeDefinition.Members.Any(m => !(m is IField && ((IField)m).IsConst))) { Message(Messages._7005, typeDefinition); } } string typeName, nmspace; if (scriptNameAttr != null && scriptNameAttr.Name != null && scriptNameAttr.Name.IsValidJavaScriptIdentifier()) { typeName = scriptNameAttr.Name; nmspace = DetermineNamespace(typeDefinition); } else if (scriptNameAttr != null && string.IsNullOrEmpty(scriptNameAttr.Name) && !string.IsNullOrEmpty(MetadataUtils.GetModuleName(typeDefinition))) { typeName = ""; nmspace = ""; } else { if (scriptNameAttr != null) { Message(Messages._7006, typeDefinition); } if (_minimizeNames && MetadataUtils.CanBeMinimized(typeDefinition) && !preserveName) { nmspace = DetermineNamespace(typeDefinition); var key = Tuple.Create(typeDefinition.ParentAssembly, nmspace); int index; _internalTypeCountPerAssemblyAndNamespace.TryGetValue(key, out index); _internalTypeCountPerAssemblyAndNamespace[key] = index + 1; typeName = "$" + index.ToString(CultureInfo.InvariantCulture); } else { typeName = GetDefaultTypeName(typeDefinition, !includeGenericArguments.Value); if (typeDefinition.DeclaringTypeDefinition != null) { if (AttributeReader.HasAttribute<IgnoreNamespaceAttribute>(typeDefinition) || AttributeReader.HasAttribute<ScriptNamespaceAttribute>(typeDefinition)) { Message(Messages._7007, typeDefinition); } var declaringName = SplitNamespacedName(GetTypeSemantics(typeDefinition.DeclaringTypeDefinition).Name); nmspace = declaringName.Item1; typeName = declaringName.Item2 + "$" + typeName; } else { nmspace = DetermineNamespace(typeDefinition); } if (MetadataUtils.CanBeMinimized(typeDefinition) && !preserveName && !typeName.StartsWith("$")) { typeName = "$" + typeName; } } } bool isSerializable = MetadataUtils.IsSerializable(typeDefinition); if (isSerializable) { var baseClass = typeDefinition.DirectBaseTypes.Single(c => c.Kind == TypeKind.Class).GetDefinition(); if (!baseClass.Equals(_systemObject) && baseClass.FullName != "System.Record" && !GetTypeSemanticsInternal(baseClass).IsSerializable) { Message(Messages._7009, typeDefinition); } foreach (var i in typeDefinition.DirectBaseTypes.Where(b => b.Kind == TypeKind.Interface && !GetTypeSemanticsInternal(b.GetDefinition()).IsSerializable)) { Message(Messages._7010, typeDefinition, i.FullName); } if (typeDefinition.Events.Any(evt => !evt.IsStatic)) { Message(Messages._7011, typeDefinition); } foreach (var m in typeDefinition.Members.Where(m => m.IsVirtual)) { Message(Messages._7023, typeDefinition, m.Name); } foreach (var m in typeDefinition.Members.Where(m => m.IsOverride)) { Message(Messages._7024, typeDefinition, m.Name); } if (typeDefinition.Kind == TypeKind.Interface && typeDefinition.Methods.Any()) { Message(Messages._7155, typeDefinition); } } else { var globalMethodsAttr = AttributeReader.ReadAttribute<GlobalMethodsAttribute>(typeDefinition); var mixinAttr = AttributeReader.ReadAttribute<MixinAttribute>(typeDefinition); if (mixinAttr != null) { if (!typeDefinition.IsStatic) { Message(Messages._7012, typeDefinition); } else if (typeDefinition.Members.Any(m => !AttributeReader.HasAttribute<CompilerGeneratedAttribute>(m) && (!(m is IMethod) || ((IMethod)m).IsConstructor))) { Message(Messages._7013, typeDefinition); } else if (typeDefinition.TypeParameterCount > 0) { Message(Messages._7014, typeDefinition); } else if (string.IsNullOrEmpty(mixinAttr.Expression)) { Message(Messages._7025, typeDefinition); } else { var split = SplitNamespacedName(mixinAttr.Expression); nmspace = split.Item1; typeName = split.Item2; } } else if (globalMethodsAttr != null) { if (!typeDefinition.IsStatic) { Message(Messages._7015, typeDefinition); } else if (typeDefinition.TypeParameterCount > 0) { Message(Messages._7017, typeDefinition); } else { nmspace = ""; typeName = ""; } } } if (importedAttr != null) { if (!string.IsNullOrEmpty(importedAttr.TypeCheckCode)) { if (importedAttr.ObeysTypeSystem) { Message(Messages._7158, typeDefinition); } ValidateInlineCode(MetadataUtils.CreateTypeCheckMethod(typeDefinition, _compilation), typeDefinition, importedAttr.TypeCheckCode, Messages._7157); } if (!string.IsNullOrEmpty(MetadataUtils.GetSerializableTypeCheckCode(typeDefinition))) { Message(Messages._7159, typeDefinition); } } bool isMutableValueType = false; if (typeDefinition.Kind == TypeKind.Struct) { isMutableValueType = AttributeReader.HasAttribute<MutableAttribute>(typeDefinition); if (!isMutableValueType) { foreach (var p in typeDefinition.Properties.Where(p => !p.IsStatic && MetadataUtils.IsAutoProperty(p) == true)) { Message(Messages._7162, p.Region, typeDefinition.FullName); } foreach (var e in typeDefinition.Events.Where(e => !e.IsStatic && MetadataUtils.IsAutoEvent(e) == true)) { Message(Messages._7162, e.Region, typeDefinition.FullName); } foreach (var f in typeDefinition.Fields.Where(f => !f.IsStatic && !f.IsReadOnly)) { Message(Messages._7162, f.Region, typeDefinition.FullName); } } } string name = !string.IsNullOrEmpty(nmspace) ? nmspace + "." + typeName : typeName; _typeSemantics[typeDefinition] = new TypeSemantics(isMutableValueType ? TypeScriptSemantics.MutableValueType(name, ignoreGenericArguments: !includeGenericArguments.Value, generateCode: importedAttr == null) : TypeScriptSemantics.NormalType(name, ignoreGenericArguments: !includeGenericArguments.Value, generateCode: importedAttr == null), isSerializable: isSerializable, isNamedValues: MetadataUtils.IsNamedValues(typeDefinition), isImported: importedAttr != null); }