internal static void ReflectConstants(Assembly /*!*/ realAssembly, DModule /*!*/ declaringModule, DualDictionary <string, DConstantDesc> /*!*/ constants) { Debug.Assert(realAssembly != null && constants != null); foreach (FieldInfo real_field in ReflectionUtils.GetGlobalFields(realAssembly, BindingFlags.Public | BindingFlags.Static)) { if (real_field.IsLiteral && !real_field.IsSpecialName) { string full_name = ClrNotationUtils.FromClrNotation(real_field.Name, true).ToString(); DConstantDesc existing; if (constants.TryGetValue(full_name, out existing)) { // can be already loaded from different module (CRL or CLib): existing.MemberAttributes |= PhpMemberAttributes.Ambiguous; } else { object value = real_field.GetValue(null); DConstantDesc const_desc = new DConstantDesc(declaringModule, PhpMemberAttributes.Public | PhpMemberAttributes.Static, value); constants.Add(full_name, const_desc, false); } } } }
/// <summary> /// Reflect global constants in <script> class. /// </summary> /// <param name="scriptType">The type representing single script.</param> /// <param name="constants">Dictionary for constants.</param> private void ReflectScriptTypeConstants(Type scriptType, DualDictionary <string, DConstantDesc> /*!*/ constants) { foreach (var field in scriptType.GetFields(BindingFlags.Public | BindingFlags.Static)) { // TODO: namespaces!! GlobalConstant constant = new GlobalConstant(this, ClrNotationUtils.FromClrNotation(field.Name, true), field); constant.SetValue(Convert.ClrLiteralToPhpLiteral(field.GetValue(null))); constants.Add(field.Name, constant.ConstantDesc, false); } }
/// <summary> /// Used by CLR modules and PHP pure modules. /// </summary> internal static void ReflectTypes(Assembly /*!*/ realAssembly, Dictionary <string, DTypeDesc> /*!*/ types) { // types: foreach (Type type in realAssembly.GetTypes()) { if (type.IsVisible) { // skip PHP types that were declared conditionally: if (PhpType.IsPhpRealType(type) && PhpType.IsRealConditionalDefinition(type)) { continue; } // converts CLR namespaces and nested types to PHP namespaces: string full_name = ClrNotationUtils.FromClrNotation(type.FullName, true).ToString(); DTypeDesc existing; if (types.TryGetValue(full_name, out existing)) { ClrTypeDesc existing_clr = existing as ClrTypeDesc; if (existing_clr != null && (existing_clr.GenericOverloads.Count > 0 || type.IsGenericTypeDefinition)) { ClrTypeDesc new_clr = DTypeDesc.Create(type) as ClrTypeDesc; if (new_clr != null) { // type is overloaded by the number of generic parameters: existing_clr.AddGenericOverload(new_clr); } else { // do not add, just mark existing with the flag: existing.MemberAttributes |= PhpMemberAttributes.Ambiguous; } } else { // do not add, just mark existing with the flag: existing.MemberAttributes |= PhpMemberAttributes.Ambiguous; } } else { types[full_name] = DTypeDesc.Create(type); } } } }
internal static void ReflectFunction(DTypeDesc declaringType, MethodInfo real_function, Dictionary <string, DRoutineDesc> functions) { if (!real_function.IsSpecialName) { QualifiedName qualified_name = ClrNotationUtils.FromClrNotation(real_function.Name, true); string full_name = qualified_name.ToString(); ClrMethod clr_function = null; DRoutineDesc existing; if (functions.TryGetValue(full_name, out existing)) { if (existing.DeclaringType.Equals(declaringType)) { Debug.Assert(existing is ClrMethodDesc, "CLR module should contain CLR methods only"); // an overload of existing CLR function: clr_function = existing.ClrMethod; } else { // ambiguous: clr_function = null; existing.MemberAttributes |= PhpMemberAttributes.Ambiguous; } } else { // new entry: clr_function = new ClrMethod(qualified_name.Name, declaringType, Enums.GetMemberAttributes(real_function), 1, real_function.ContainsGenericParameters); functions.Add(full_name, clr_function.ClrMethodDesc); } if (clr_function != null) { ClrMethod.Overload overload; clr_function.AddOverload(real_function, out overload); } } }
/// <summary> /// Reflect PHP classes declared statically in the given script <c>type</c>. /// </summary> /// <param name="scriptType">Script type to reflect.</param> /// <param name="types">List of types to reflect to.</param> private static void ReflectScriptTypeClasses(Type scriptType, Dictionary <string, DTypeDesc> /*!*/ types) { ScriptDeclaresAttribute script_declares = ScriptDeclaresAttribute.Reflect(scriptType); if (script_declares == null) { return; } var module = scriptType.Module; foreach (var typeToken in script_declares.DeclaredTypes) { Type type = module.ResolveType(typeToken); // reflect PHP class, skip PHP types that were declared conditionally if (PhpType.IsPhpRealType(type) && !PhpType.IsRealConditionalDefinition(type)) { // converts CLR namespaces and nested types to PHP namespaces: string full_name = ClrNotationUtils.FromClrNotation(type.FullName, true).ToString(); // Creating PhpTypeDesc with cache lookup since this type can be in the cache already: // Also force PHP type, because we already checked PhpType.IsPhpRealType(type) PhpTypeDesc phpType = (PhpTypeDesc)DTypeDesc.Create(type.TypeHandle); DTypeDesc existing; if (types.TryGetValue(full_name, out existing)) { // TODO (TP): can be generic overload!! existing.MemberAttributes |= PhpMemberAttributes.Ambiguous; } types.Add(full_name, phpType); } } }