private void ResolveEnum(IExpression enumExpr, IExpression constantExpr) { Contract.Requires(enumExpr != null); Contract.Requires(constantExpr != null); var targetType = enumExpr.Type.ResolvedType; if (targetType.IsEnum && constantExpr is ICompileTimeConstant) { var constant = (ICompileTimeConstant)constantExpr; var value = targetType.Fields.FirstOrDefault(f => f.IsCompileTimeConstant && constant.Value.Equals(f.CompileTimeValue.Value)); if (value != null) { // Celeriac uses reflection-style names for inner types, need to be consistent here var name = string.Join(".", TypeHelper.GetTypeName(targetType, NameFormattingOptions.UseReflectionStyleForNestedTypeNames), value.Name); TryAdd(constantExpr, name); AddInstanceExpr(targetType, constantExpr); StaticNames.Add(constantExpr); } else { try { // Enum is defined in another assembly var enumType = TypeManager.ConvertAssemblyQualifiedNameToType( TypeManager.ConvertCCITypeToAssemblyQualifiedName(targetType)).GetSingleType; Contract.Assume(enumType.IsEnum, "CCI enum type resolved to non-enum type"); var name = string.Join(".", enumType.FullName, enumType.GetEnumName(constant.Value)); TryAdd(constantExpr, name); } catch (Exception) { // Issue #84: debug errors locating enums in other assemblies } } } }
private void HandleBundle(IExpression outer, object definition, IExpression instance) { Contract.Requires(outer != null); Contract.Requires(definition != null); if (definition is IParameterDefinition) { var name = ((IParameterDefinition)definition).Name.Value; if (!string.IsNullOrEmpty(name)) { TryAdd(outer, name); } else { // NO OP: implicit this of superclass is not named (e.g., for default ctor of subclass) } } else if (definition is IPropertyDefinition) { var name = ((IPropertyDefinition)definition).Name.Value; Contract.Assume(!string.IsNullOrWhiteSpace(name), Context()); TryAdd(outer, name); } else if (definition is IFieldReference) { var field = ((IFieldReference)definition).ResolvedField; if (!(field is Dummy) && !field.Attributes.Any(a => TypeManager.IsCompilerGenerated(field))) { if (field.IsStatic) { var container = field.ContainingType.ResolvedType; // Celeriac uses reflection-style names for inner types, need to be consistent here var name = string.Join(".", TypeHelper.GetTypeName(container, NameFormattingOptions.UseReflectionStyleForNestedTypeNames), field.Name.Value); TryAdd(outer, name); AddInstanceExpr(container, outer); StaticNames.Add(outer); } else { Contract.Assume(instance != null, "Non-static field reference '" + field.Name + "' has no provided instance; " + Context()); if (instance != null && NameTable.ContainsKey(instance)) { var name = NameTable[instance] + "." + field.Name; TryAdd(outer, name); AddInstanceExpr(Type, outer); } else { // NO OP (we aren't tracking the name of the instance) } } } } else if (definition is IArrayIndexer) { var def = (IArrayIndexer)definition; if (NameTable.ContainsKey(def.IndexedObject)) { TryAdd(outer, FormElementsExpression(NameTable[def.IndexedObject])); // propogate instance expression information if (InstanceExpressionsReferredTypes.ContainsKey(def.IndexedObject)) { AddInstanceExpr(InstanceExpressionsReferredTypes[def.IndexedObject], outer); } } else { // NO OP (we aren't tracking the name of the instance) } } else if (definition is ILocalDefinition) { var def = (ILocalDefinition)definition; TryAdd(outer, "<local>" + def.Name.Value); } else if (definition is IAddressDereference) { // NO OP } else { throw new NotSupportedException("Comparability: Unexpected bundled type " + definition.GetType().Name); } }