// <summary> // Resolve is used in method definitions // </summary> public virtual Type Resolve(IMemberContext rc) { if (parameter_type != null) { return(parameter_type); } if (attributes != null) { attributes.AttachTo(this, rc); } TypeExpr texpr = TypeName.ResolveAsTypeTerminal(rc, false); if (texpr == null) { return(null); } parameter_type = texpr.Type; // Ignore all checks for dummy members AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod; if (pem != null && pem.IsDummy) { return(parameter_type); } if (default_expr != null) { ResolveContext ec = new ResolveContext(rc); default_expr = default_expr.Resolve(ec); if (default_expr != null) { Constant value = default_expr as Constant; if (value == null) { if (default_expr != null) { bool is_valid = false; if (default_expr is DefaultValueExpression) { is_valid = true; } else if (default_expr is New && ((New)default_expr).IsDefaultValueType) { is_valid = TypeManager.IsEqual(parameter_type, default_expr.Type) || (TypeManager.IsNullableType(parameter_type) && Convert.ImplicitNulableConversion(ec, default_expr, parameter_type) != EmptyExpression.Null); } else { rc.Compiler.Report.Error(1736, default_expr.Location, "The expression being assigned to optional parameter `{0}' must be a constant or default value", Name); is_valid = true; } if (!is_valid) { default_expr = null; ec.Compiler.Report.Error(1763, Location, "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", Name, GetSignatureForError()); } } } else { Constant c = value.ConvertImplicitly(parameter_type); if (c == null) { if (parameter_type == TypeManager.object_type) { rc.Compiler.Report.Error(1763, Location, "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", Name, GetSignatureForError()); } else { rc.Compiler.Report.Error(1750, Location, "Optional parameter value `{0}' cannot be converted to parameter type `{1}'", value.GetValue(), GetSignatureForError()); } default_expr = null; } } } } if ((modFlags & Parameter.Modifier.ISBYREF) != 0 && TypeManager.IsSpecialType(parameter_type)) { rc.Compiler.Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'", GetSignatureForError()); return(null); } TypeManager.CheckTypeVariance(parameter_type, (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant, rc); if (TypeManager.IsGenericParameter(parameter_type)) { return(parameter_type); } if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) { rc.Compiler.Report.Error(721, Location, "`{0}': static types cannot be used as parameters", texpr.GetSignatureForError()); return(parameter_type); } if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType(parameter_type))) { rc.Compiler.Report.Error(1103, Location, "The extension method cannot be of type `{0}'", TypeManager.CSharpName(parameter_type)); } return(parameter_type); }
// // Is this member accessible from invocation context // public bool IsAccessible(IMemberContext ctx) { var ma = Modifiers & Modifiers.AccessibilityMask; if (ma == Modifiers.PUBLIC) { return(true); } var parentType = /* this as TypeSpec ?? */ DeclaringType; var ctype = ctx.CurrentType; if (ma == Modifiers.PRIVATE) { if (ctype == null) { return(false); } // // It's only accessible to the current class or children // if (parentType.MemberDefinition == ctype.MemberDefinition) { return(true); } return(TypeManager.IsNestedChildOf(ctype, parentType.MemberDefinition)); } if ((ma & Modifiers.INTERNAL) != 0) { bool b; var assembly = ctype == null ? ctx.Module.DeclaringAssembly : ctype.MemberDefinition.DeclaringAssembly; if (parentType == null) { b = ((ITypeDefinition)MemberDefinition).IsInternalAsPublic(assembly); } else { b = DeclaringType.MemberDefinition.IsInternalAsPublic(assembly); } if (b || ma == Modifiers.INTERNAL) { return(b); } } // // Checks whether `ctype' is a subclass or nested child of `parentType'. // while (ctype != null) { if (TypeManager.IsFamilyAccessible(ctype, parentType)) { return(true); } // Handle nested types. ctype = ctype.DeclaringType; // TODO: Untested ??? } return(false); }
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) { if (a.IsValidSecurityAttribute()) { if (declarative_security == null) { declarative_security = new ListDictionary(); } a.ExtractSecurityPermissionSet(declarative_security); return; } if (a.Type == pa.AssemblyCulture) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } if (RootContext.Target == Target.Exe) { a.Error_AttributeEmitError("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); return; } } if (a.Type == pa.AssemblyVersion) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } value = value.Replace('*', '0'); if (!IsValidAssemblyVersion(value)) { a.Error_AttributeEmitError(string.Format("Specified version `{0}' is not valid", value)); return; } } if (a.Type == pa.InternalsVisibleTo && !CheckInternalsVisibleAttribute(a)) { return; } if (a.Type == pa.TypeForwarder) { Type t = a.GetArgumentType(); if (t == null || TypeManager.HasElementType(t)) { Report.Error(735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute"); return; } t = TypeManager.DropGenericTypeArguments(t); if (emitted_forwarders == null) { emitted_forwarders = new ListDictionary(); } else if (emitted_forwarders.Contains(t)) { Report.SymbolRelatedToPreviousError(((Attribute)emitted_forwarders[t]).Location, null); Report.Error(739, a.Location, "A duplicate type forward of type `{0}'", TypeManager.CSharpName(t)); return; } emitted_forwarders.Add(t, a); if (TypeManager.LookupDeclSpace(t) != null) { Report.SymbolRelatedToPreviousError(t); Report.Error(729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", TypeManager.CSharpName(t)); return; } if (t.DeclaringType != null) { Report.Error(730, a.Location, "Cannot forward type `{0}' because it is a nested type", TypeManager.CSharpName(t)); return; } if (add_type_forwarder == null) { add_type_forwarder = typeof(AssemblyBuilder).GetMethod("AddTypeForwarder", BindingFlags.NonPublic | BindingFlags.Instance); if (add_type_forwarder == null) { Report.RuntimeMissingSupport(a.Location, "TypeForwardedTo attribute"); return; } } add_type_forwarder.Invoke(Builder, new object[] { t }); return; } if (a.Type == pa.Extension) { a.Error_MisusedExtensionAttribute(); return; } Builder.SetCustomAttribute(cb); }
protected override Expression DoResolve(ResolveContext ec) { constructor_method = Delegate.GetConstructor(type); var invoke_method = Delegate.GetInvokeMethod(type); Arguments arguments = CreateDelegateMethodArguments(ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve(ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (method_group == null) { return(null); } var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error(1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError()); return(null); } if (!AllowSpecialMethodsInvocation) { Invocation.IsSpecialMethodInvocation(ec, delegate_method, loc); } ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType(e_type)) { ec.Report.Error(1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError(), e_type.GetSignatureForError()); } } TypeSpec rt = delegate_method.ReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { rt = ec.BuiltinTypes.Object; } if (!Delegate.IsTypeCovariant(ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression(delegate_method.ReturnType, loc); Error_ConversionFailed(ec, delegate_method, ret_expr); } if (delegate_method.IsConditionallyExcluded(ec, loc)) { ec.Report.SymbolRelatedToPreviousError(delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error(762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError()); } else { ec.Report.Error(1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature(delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType(expr.Type))) { method_group.InstanceExpression = new BoxedCast(expr, ec.BuiltinTypes.Object); } eclass = ExprClass.Value; return(this); }
public void ResolveDefaultValue(ResolveContext rc) { // // Default value was specified using an expression // if (default_expr != null) { ((DefaultParameterValueExpression)default_expr).Resolve(rc, this); return; } if (attributes == null) { return; } var opt_attr = attributes.Search(rc.Module.PredefinedAttributes.OptionalParameter); var def_attr = attributes.Search(rc.Module.PredefinedAttributes.DefaultParameterValue); if (def_attr != null) { if (def_attr.Resolve() == null) { return; } var default_expr_attr = def_attr.GetParameterDefaultValue(); if (default_expr_attr == null) { return; } var dpa_rc = def_attr.CreateResolveContext(); default_expr = default_expr_attr.Resolve(dpa_rc); if (default_expr is BoxedCast) { default_expr = ((BoxedCast)default_expr).Child; } Constant c = default_expr as Constant; if (c == null) { if (parameter_type == TypeManager.object_type) { rc.Compiler.Report.Error(1910, default_expr.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute", default_expr.Type.GetSignatureForError()); } else { rc.Compiler.Report.Error(1909, default_expr.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'", default_expr.Type.GetSignatureForError());; } default_expr = null; return; } if (TypeSpecComparer.IsEqual(default_expr.Type, parameter_type) || (default_expr is NullConstant && TypeManager.IsReferenceType(parameter_type) && !parameter_type.IsGenericParameter) || TypeSpecComparer.IsEqual(parameter_type, TypeManager.object_type)) { return; } // // LAMESPEC: Some really weird csc behaviour which we have to mimic // User operators returning same type as parameter type are considered // valid for this attribute only // // struct S { public static implicit operator S (int i) {} } // // void M ([DefaultParameterValue (3)]S s) // var expr = Convert.ImplicitUserConversion(dpa_rc, default_expr, parameter_type, loc); if (expr != null && TypeSpecComparer.IsEqual(expr.Type, parameter_type)) { return; } rc.Compiler.Report.Error(1908, default_expr.Location, "The type of the default value should match the type of the parameter"); return; } if (opt_attr != null) { default_expr = EmptyExpression.MissingValue; } }
// // Emits the right opcode to store to an array // public void EmitArrayStore(ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) { ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(OpCodes.Call, ac.GetSetMethod()); return; } var type = ac.Element; if (type.IsEnum) { type = EnumSpec.GetUnderlyingType(type); } if (type == TypeManager.byte_type || type == TypeManager.sbyte_type || type == TypeManager.bool_type) { Emit(OpCodes.Stelem_I1); } else if (type == TypeManager.short_type || type == TypeManager.ushort_type || type == TypeManager.char_type) { Emit(OpCodes.Stelem_I2); } else if (type == TypeManager.int32_type || type == TypeManager.uint32_type) { Emit(OpCodes.Stelem_I4); } else if (type == TypeManager.int64_type || type == TypeManager.uint64_type) { Emit(OpCodes.Stelem_I8); } else if (type == TypeManager.float_type) { Emit(OpCodes.Stelem_R4); } else if (type == TypeManager.double_type) { Emit(OpCodes.Stelem_R8); } else if (type == TypeManager.intptr_type) { Emit(OpCodes.Stobj, type); } else if (TypeManager.IsStruct(type)) { Emit(OpCodes.Stobj, type); } else if (type.IsGenericParameter) { Emit(OpCodes.Stelem, type); } else if (type.IsPointer) { Emit(OpCodes.Stelem_I); } else { Emit(OpCodes.Stelem_Ref); } }
protected override bool DoDefineMembers() { var builtin_types = Compiler.BuiltinTypes; var ctor_parameters = ParametersCompiled.CreateFullyResolved( new [] { new Parameter(new TypeExpression(builtin_types.Object, Location), "object", Parameter.Modifier.NONE, null, Location), new Parameter(new TypeExpression(builtin_types.IntPtr, Location), "method", Parameter.Modifier.NONE, null, Location) }, new [] { builtin_types.Object, builtin_types.IntPtr } ); Constructor = new Constructor(this, Constructor.ConstructorName, Modifiers.PUBLIC, null, ctor_parameters, Location); Constructor.Define(); // // Here the various methods like Invoke, BeginInvoke etc are defined // // First, call the `out of band' special method for // defining recursively any types we need: // var p = parameters; if (!p.Resolve(this)) { return(false); } // // Invoke method // // Check accessibility foreach (var partype in p.Types) { if (!IsAccessibleAs(partype)) { Report.SymbolRelatedToPreviousError(partype); Report.Error(59, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'", partype.GetSignatureForError(), GetSignatureForError()); } } var ret_type = ReturnType.ResolveAsType(this); if (ret_type == null) { return(false); } // // We don't have to check any others because they are all // guaranteed to be accessible - they are standard types. // if (!IsAccessibleAs(ret_type)) { Report.SymbolRelatedToPreviousError(ret_type); Report.Error(58, Location, "Inconsistent accessibility: return type `" + ret_type.GetSignatureForError() + "' is less " + "accessible than delegate `" + GetSignatureForError() + "'"); return(false); } CheckProtectedModifier(); if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType) { Method.Error1599(Location, ret_type, Report); return(false); } TypeManager.CheckTypeVariance(ret_type, Variance.Covariant, this); var resolved_rt = new TypeExpression(ret_type, Location); InvokeBuilder = new Method(this, resolved_rt, MethodModifiers, new MemberName(InvokeMethodName), p, null); InvokeBuilder.Define(); // // Don't emit async method for compiler generated delegates (e.g. dynamic site containers) // if (!IsCompilerGenerated) { DefineAsyncMethods(Parameters.CallingConvention, resolved_rt); } return(true); }
TypeExpr CreateSiteType(CompilerContext ctx, bool isStatement, int dyn_args_count) { int default_args = isStatement ? 1 : 2; bool has_ref_out_argument = false; FullNamedExpression[] targs = new FullNamedExpression[dyn_args_count + default_args]; targs [0] = new TypeExpression(TypeManager.call_site_type, loc); for (int i = 0; i < dyn_args_count; ++i) { Type arg_type; Argument a = arguments [i]; if (a.Type == TypeManager.null_type) { arg_type = TypeManager.object_type; } else { arg_type = TypeManager.TypeToReflectionType(a.Type); } if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref) { has_ref_out_argument = true; } targs [i + 1] = new TypeExpression(arg_type, loc); } TypeExpr del_type = null; if (!has_ref_out_argument) { string d_name = isStatement ? "Action`" : "Func`"; Type t = TypeManager.CoreLookupType(ctx, "System", d_name + (dyn_args_count + default_args), Kind.Delegate, false); if (t != null) { if (!isStatement) { targs[targs.Length - 1] = new TypeExpression(TypeManager.TypeToReflectionType(type), loc); } del_type = new GenericTypeExpr(t, new TypeArguments(targs), loc); } } // No appropriate predefined delegate found if (del_type == null) { Type rt = isStatement ? TypeManager.void_type : type; Parameter[] p = new Parameter [dyn_args_count + 1]; p[0] = new Parameter(targs [0], "p0", Parameter.Modifier.NONE, null, loc); for (int i = 1; i < dyn_args_count + 1; ++i) { p[i] = new Parameter(targs[i], "p" + i.ToString("X"), arguments[i - 1].Modifier, null, loc); } TypeContainer parent = CreateSiteContainer(); Delegate d = new Delegate(parent.NamespaceEntry, parent, new TypeExpression(rt, loc), Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED, new MemberName("Container" + container_counter++.ToString("X")), new ParametersCompiled(p), null); d.DefineType(); d.Define(); parent.AddDelegate(d); del_type = new TypeExpression(d.TypeBuilder, loc); } TypeExpr site_type = new GenericTypeExpr(TypeManager.generic_call_site_type, new TypeArguments(del_type), loc); return(site_type); }
/// <summary> /// Verifies that any pending abstract methods or interface methods /// were implemented. /// </summary> public bool VerifyPendingMethods(Report Report) { int top = pending_implementations.Length; bool errors = false; int i; for (i = 0; i < top; i++) { TypeSpec type = pending_implementations [i].type; bool base_implements_type = type.IsInterface && container.BaseType != null && container.BaseType.ImplementsInterface(type, false); for (int j = 0; j < pending_implementations [i].methods.Count; ++j) { var mi = pending_implementations[i].methods[j]; if (mi == null) { continue; } if (type.IsInterface) { var need_proxy = pending_implementations [i].need_proxy [j]; if (need_proxy != null) { DefineProxy(type, need_proxy, mi); continue; } if (pending_implementations [i].optional) { continue; } MethodSpec candidate = null; if (base_implements_type || BaseImplements(type, mi, out candidate)) { continue; } if (candidate == null) { MethodData md = pending_implementations [i].found [j]; if (md != null) { candidate = md.method.Spec; } } Report.SymbolRelatedToPreviousError(mi); if (candidate != null) { Report.SymbolRelatedToPreviousError(candidate); if (candidate.IsStatic) { Report.Error(736, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is static", container.GetSignatureForError(), mi.GetSignatureForError(), TypeManager.CSharpSignature(candidate)); } else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0) { Report.Error(737, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public", container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError()); } else { Report.Error(738, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' return type `{3}' does not match interface member return type `{4}'", container.GetSignatureForError(), mi.GetSignatureForError(), TypeManager.CSharpSignature(candidate), TypeManager.CSharpName(candidate.ReturnType), TypeManager.CSharpName(mi.ReturnType)); } } else { Report.Error(535, container.Location, "`{0}' does not implement interface member `{1}'", container.GetSignatureForError(), mi.GetSignatureForError()); } } else { Report.SymbolRelatedToPreviousError(mi); Report.Error(534, container.Location, "`{0}' does not implement inherited abstract member `{1}'", container.GetSignatureForError(), mi.GetSignatureForError()); } errors = true; } } return(errors); }
// // Processes "see" or "seealso" elements. // Checks cref attribute. // private static void HandleXrefCommon(MemberCore mc, DeclSpace ds, XmlElement xref) { string cref = xref.GetAttribute("cref").Trim(wsChars); // when, XmlReader, "if (cref == null)" if (!xref.HasAttribute("cref")) { return; } if (cref.Length == 0) { Report.Warning(1001, 1, mc.Location, "Identifier expected"); } // ... and continue until CS1584. string signature; // "x:" are stripped string name; // method invokation "(...)" are removed string parameters; // method parameter list // When it found '?:' ('T:' 'M:' 'F:' 'P:' 'E:' etc.), // MS ignores not only its member kind, but also // the entire syntax correctness. Nor it also does // type fullname resolution i.e. "T:List(int)" is kept // as T:List(int), not // T:System.Collections.Generic.List<System.Int32> if (cref.Length > 2 && cref [1] == ':') { return; } else { signature = cref; } // Also note that without "T:" any generic type // indication fails. int parens_pos = signature.IndexOf('('); int brace_pos = parens_pos >= 0 ? -1 : signature.IndexOf('['); if (parens_pos > 0 && signature [signature.Length - 1] == ')') { name = signature.Substring(0, parens_pos).Trim(wsChars); parameters = signature.Substring(parens_pos + 1, signature.Length - parens_pos - 2).Trim(wsChars); } else if (brace_pos > 0 && signature [signature.Length - 1] == ']') { name = signature.Substring(0, brace_pos).Trim(wsChars); parameters = signature.Substring(brace_pos + 1, signature.Length - brace_pos - 2).Trim(wsChars); } else { name = signature; parameters = null; } Normalize(mc, ref name); string identifier = GetBodyIdentifierFromName(name); // Check if identifier is valid. // This check is not necessary to mark as error, but // csc specially reports CS1584 for wrong identifiers. string [] name_elems = identifier.Split('.'); for (int i = 0; i < name_elems.Length; i++) { string nameElem = GetBodyIdentifierFromName(name_elems [i]); if (i > 0) { Normalize(mc, ref nameElem); } if (!Tokenizer.IsValidIdentifier(nameElem) && nameElem.IndexOf("operator") < 0) { Report.Warning(1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'", mc.GetSignatureForError(), cref); xref.SetAttribute("cref", "!:" + signature); return; } } // check if parameters are valid Type [] parameter_types; if (parameters == null) { parameter_types = null; } else if (parameters.Length == 0) { parameter_types = Type.EmptyTypes; } else { string [] param_list = parameters.Split(','); ArrayList plist = new ArrayList(); for (int i = 0; i < param_list.Length; i++) { string param_type_name = param_list [i].Trim(wsChars); Normalize(mc, ref param_type_name); Type param_type = FindDocumentedType(mc, param_type_name, ds, cref); if (param_type == null) { Report.Warning(1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'", (i + 1).ToString(), cref); return; } plist.Add(param_type); } parameter_types = plist.ToArray(typeof(Type)) as Type []; } Type type = FindDocumentedType(mc, name, ds, cref); if (type != null // delegate must not be referenced with args && (!TypeManager.IsDelegateType(type) || parameter_types == null)) { string result = GetSignatureForDoc(type) + (brace_pos < 0 ? String.Empty : signature.Substring(brace_pos)); xref.SetAttribute("cref", "T:" + result); return; // a type } int period = name.LastIndexOf('.'); if (period > 0) { string typeName = name.Substring(0, period); string member_name = name.Substring(period + 1); Normalize(mc, ref member_name); type = FindDocumentedType(mc, typeName, ds, cref); int warn_result; if (type != null) { FoundMember fm = FindDocumentedMember(mc, type, member_name, parameter_types, ds, out warn_result, cref, true, name); if (warn_result > 0) { return; } if (!fm.IsEmpty) { MemberInfo mi = fm.Member; // we cannot use 'type' directly // to get its name, since mi // could be from DeclaringType // for nested types. xref.SetAttribute("cref", GetMemberDocHead(mi.MemberType) + GetSignatureForDoc(fm.Type) + "." + member_name + GetParametersFormatted(mi)); return; // a member of a type } } } else { int warn_result; FoundMember fm = FindDocumentedMember(mc, ds.TypeBuilder, name, parameter_types, ds, out warn_result, cref, true, name); if (warn_result > 0) { return; } if (!fm.IsEmpty) { MemberInfo mi = fm.Member; // we cannot use 'type' directly // to get its name, since mi // could be from DeclaringType // for nested types. xref.SetAttribute("cref", GetMemberDocHead(mi.MemberType) + GetSignatureForDoc(fm.Type) + "." + name + GetParametersFormatted(mi)); return; // local member name } } // It still might be part of namespace name. Namespace ns = ds.NamespaceEntry.NS.GetNamespace(name, false); if (ns != null) { xref.SetAttribute("cref", "N:" + ns.GetSignatureForError()); return; // a namespace } if (RootNamespace.Global.IsNamespace(name)) { xref.SetAttribute("cref", "N:" + name); return; // a namespace } Report.Warning(1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved", mc.GetSignatureForError(), cref); xref.SetAttribute("cref", "!:" + name); }
public FieldSpec GetField(string name, TypeSpec memberType, Location loc) { return(TypeManager.GetPredefinedField(type, name, loc, memberType)); }
private static MemberInfo FindDocumentedMemberNoNest( MemberCore mc, Type type, string member_name, Type [] param_list, DeclSpace ds, out int warning_type, string cref, bool warn419, string name_for_error) { warning_type = 0; MemberInfo [] mis; if (param_list == null) { // search for fields/events etc. mis = TypeManager.MemberLookup(type, null, type, MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, member_name, null); mis = FilterOverridenMembersOut(mis); if (mis == null || mis.Length == 0) { return(null); } if (warn419 && IsAmbiguous(mis)) { Report419(mc, name_for_error, mis); } return(mis [0]); } MethodSignature msig = new MethodSignature(member_name, null, param_list); mis = FindMethodBase(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, msig); if (warn419 && mis.Length > 0) { if (IsAmbiguous(mis)) { Report419(mc, name_for_error, mis); } return(mis [0]); } // search for operators (whose parameters exactly // matches with the list) and possibly report CS1581. string oper = null; string return_type_name = null; if (member_name.StartsWith("implicit operator ")) { Operator.GetMetadataName(Operator.OpType.Implicit); return_type_name = member_name.Substring(18).Trim(wsChars); } else if (member_name.StartsWith("explicit operator ")) { oper = Operator.GetMetadataName(Operator.OpType.Explicit); return_type_name = member_name.Substring(18).Trim(wsChars); } else if (member_name.StartsWith("operator ")) { oper = member_name.Substring(9).Trim(wsChars); switch (oper) { // either unary or binary case "+": oper = param_list.Length == 2 ? Operator.GetMetadataName(Operator.OpType.Addition) : Operator.GetMetadataName(Operator.OpType.UnaryPlus); break; case "-": oper = param_list.Length == 2 ? Operator.GetMetadataName(Operator.OpType.Subtraction) : Operator.GetMetadataName(Operator.OpType.UnaryNegation); break; default: oper = Operator.GetMetadataName(oper); if (oper != null) { break; } warning_type = 1584; Report.Warning(1020, 1, mc.Location, "Overloadable {0} operator is expected", param_list.Length == 2 ? "binary" : "unary"); Report.Warning(1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'", mc.GetSignatureForError(), cref); return(null); } } // here we still don't consider return type (to // detect CS1581 or CS1002+CS1584). msig = new MethodSignature(oper, null, param_list); mis = FindMethodBase(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, msig); if (mis.Length == 0) { return(null); // CS1574 } MemberInfo mi = mis [0]; Type expected = mi is MethodInfo ? ((MethodInfo)mi).ReturnType : mi is PropertyInfo ? ((PropertyInfo)mi).PropertyType : null; if (return_type_name != null) { Type returnType = FindDocumentedType(mc, return_type_name, ds, cref); if (returnType == null || returnType != expected) { warning_type = 1581; Report.Warning(1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref); return(null); } } return(mis [0]); }
protected override ParametersCompiled ResolveParameters(ResolveContext ec, TypeInferenceContext tic, Type delegateType) { if (!TypeManager.IsDelegateType(delegateType)) { return(null); } AParametersCollection d_params = TypeManager.GetDelegateParameters(ec, delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters(ec, delegateType, d_params)) { return(null); } return(Parameters); } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility(ec, delegateType, d_params, ec.IsInProbingMode)) { return(null); } Type [] ptypes = new Type [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0) { return(null); } Type d_param = d_params.Types [i]; #if MS_COMPATIBLE // Blablabla, because reflection does not work with dynamic types if (d_param.IsGenericParameter) { d_param = delegateType.GetGenericArguments() [d_param.GenericParameterPosition]; } #endif // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument(d_param); } ptypes [i] = d_param; ((ImplicitLambdaParameter)Parameters.FixedParameters [i]).Type = d_param; } Parameters.Types = ptypes; return(Parameters); }
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.Type == TypeManager.in_attribute_type && ModFlags == Modifier.OUT) { Report.Error(36, a.Location, "An out parameter cannot have the `In' attribute"); return; } if (a.Type == TypeManager.param_array_type) { Report.Error(674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead"); return; } if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF && TypeManager.in_attribute_type != null && !OptAttributes.Contains(TypeManager.in_attribute_type)) { Report.Error(662, a.Location, "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither"); return; } if (a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning(3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead"); } // TypeManager.default_parameter_value_attribute_type is null if !NET_2_0, or if System.dll is not referenced if (a.Type == TypeManager.default_parameter_value_attribute_type) { object val = a.GetParameterDefaultValue(); if (val != null) { Type t = val.GetType(); if (t.IsArray || TypeManager.IsSubclassOf(t, TypeManager.type_type)) { if (parameter_type == TypeManager.object_type) { if (!t.IsArray) { t = TypeManager.type_type; } Report.Error(1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute", TypeManager.CSharpName(t)); } else { Report.Error(1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'", TypeManager.CSharpName(parameter_type));; } return; } } if (parameter_type == TypeManager.object_type || (val == null && !TypeManager.IsValueType(parameter_type)) || (val != null && TypeManager.TypeToCoreType(val.GetType()) == parameter_type)) { builder.SetConstant(val); } else { Report.Error(1908, a.Location, "The type of the default value should match the type of the parameter"); } return; } base.ApplyAttributeBuilder(a, cb); }
public ArrayInitializer CreateDynamicBinderArguments(ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer(args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace(loc); foreach (Argument a in args) { Arguments dargs = new Arguments(2); // CSharpArgumentInfoFlags.None = 0 const string info_flags_enum = "CSharpArgumentInfoFlags"; Expression info_flags = new IntLiteral(rc.BuiltinTypes, 0, loc); if (a.Expr is Constant) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "Constant", loc), loc); } else if (a.ArgType == Argument.AType.Ref) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsRef", loc), loc); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc); } else if (a.ArgType == Argument.AType.Out) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsOut", loc), loc); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc); } else if (a.ArgType == Argument.AType.DynamicTypeName) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsStaticType", loc), loc); } var arg_type = a.Expr.Type; if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; if (mg != null) { rc.Report.Error(1976, a.Expr.Location, "The method group `{0}' cannot be used as an argument of dynamic operation. Consider using parentheses to invoke the method", mg.Name); } else if (arg_type == InternalType.AnonymousMethod) { rc.Report.Error(1977, a.Expr.Location, "An anonymous method or lambda expression cannot be used as an argument of dynamic operation. Consider using a cast"); } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error(1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", TypeManager.CSharpName(arg_type)); } info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc); } string named_value; NamedArgument na = a as NamedArgument; if (na != null) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "NamedArgument", loc), loc); named_value = na.Name; } else { named_value = null; } dargs.Add(new Argument(info_flags)); dargs.Add(new Argument(new StringLiteral(rc.BuiltinTypes, named_value, loc))); all.Add(new Invocation(new MemberAccess(new MemberAccess(binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return(all); }
public static void Error_ConstantCanBeInitializedWithNullOnly(Type type, Location loc, string name) { Report.Error(134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null", name, TypeManager.CSharpName(type)); }
public void ApplyAttributeBuilder(Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.IsValidSecurityAttribute()) { a.ExtractSecurityPermissionSet(ctor, ref declarative_security); return; } if (a.Type == pa.AssemblyCulture) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } if (Compiler.Settings.Target == Target.Exe) { a.Error_AttributeEmitError("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); return; } if (value == "neutral") { value = ""; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetCulture(value, a.Location); } IsSatelliteAssembly = true; return; } if (a.Type == pa.AssemblyVersion) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } var vinfo = IsValidAssemblyVersion(value, true); if (vinfo == null) { a.Error_AttributeEmitError(string.Format("Specified version `{0}' is not valid", value)); return; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetVersion(vinfo, a.Location); } return; } if (a.Type == pa.AssemblyAlgorithmId) { const int pos = 2; // skip CA header uint alg = (uint)cdata [pos]; alg |= ((uint)cdata [pos + 1]) << 8; alg |= ((uint)cdata [pos + 2]) << 16; alg |= ((uint)cdata [pos + 3]) << 24; if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetAlgorithmId(alg, a.Location); } return; } if (a.Type == pa.AssemblyFlags) { const int pos = 2; // skip CA header uint flags = (uint)cdata[pos]; flags |= ((uint)cdata [pos + 1]) << 8; flags |= ((uint)cdata [pos + 2]) << 16; flags |= ((uint)cdata [pos + 3]) << 24; // Ignore set PublicKey flag if assembly is not strongnamed if ((flags & (uint)AssemblyNameFlags.PublicKey) != 0 && public_key == null) { flags &= ~(uint)AssemblyNameFlags.PublicKey; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetFlags(flags, a.Location); } return; } if (a.Type == pa.TypeForwarder) { TypeSpec t = a.GetArgumentType(); if (t == null || TypeManager.HasElementType(t)) { Report.Error(735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute"); return; } if (emitted_forwarders == null) { emitted_forwarders = new Dictionary <ITypeDefinition, Attribute> (); } else if (emitted_forwarders.ContainsKey(t.MemberDefinition)) { Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null); Report.Error(739, a.Location, "A duplicate type forward of type `{0}'", t.GetSignatureForError()); return; } emitted_forwarders.Add(t.MemberDefinition, a); if (t.MemberDefinition.DeclaringAssembly == this) { Report.SymbolRelatedToPreviousError(t); Report.Error(729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", t.GetSignatureForError()); return; } if (t.IsNested) { Report.Error(730, a.Location, "Cannot forward type `{0}' because it is a nested type", t.GetSignatureForError()); return; } builder_extra.AddTypeForwarder(t.GetDefinition(), a.Location); return; } if (a.Type == pa.Extension) { a.Error_MisusedExtensionAttribute(); return; } if (a.Type == pa.InternalsVisibleTo) { string assembly_name = a.GetString(); if (assembly_name.Length == 0) { return; } #if STATIC ParsedAssemblyName aname; ParseAssemblyResult r = Fusion.ParseAssemblyName(assembly_name, out aname); if (r != ParseAssemblyResult.OK) { Report.Warning(1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved", assembly_name); return; } if (aname.Version != null || aname.Culture != null || aname.ProcessorArchitecture != ProcessorArchitecture.None) { Report.Error(1725, a.Location, "Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified", assembly_name); return; } if (public_key != null && !aname.HasPublicKey) { Report.Error(1726, a.Location, "Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations", assembly_name); return; } #endif } else if (a.Type == pa.RuntimeCompatibility) { wrap_non_exception_throws_custom = true; } else if (a.Type == pa.AssemblyFileVersion) { vi_product_version = a.GetString(); if (string.IsNullOrEmpty(vi_product_version) || IsValidAssemblyVersion(vi_product_version, false) == null) { Report.Warning(1607, 1, a.Location, "The version number `{0}' specified for `{1}' is invalid", vi_product_version, a.Name); return; } } else if (a.Type == pa.AssemblyProduct) { vi_product = a.GetString(); } else if (a.Type == pa.AssemblyCompany) { vi_company = a.GetString(); } else if (a.Type == pa.AssemblyDescription) { // TODO: Needs extra api } else if (a.Type == pa.AssemblyCopyright) { vi_copyright = a.GetString(); } else if (a.Type == pa.AssemblyTrademark) { vi_trademark = a.GetString(); } SetCustomAttribute(ctor, cdata); }
public static void Error_InvalidConstantType(Type t, Location loc) { Report.Error(283, loc, "The type `{0}' cannot be declared const", TypeManager.CSharpName(t)); }
// // Load the object from the pointer. // public void EmitLoadFromPtr(TypeSpec t) { if (t == TypeManager.int32_type) { ig.Emit(OpCodes.Ldind_I4); } else if (t == TypeManager.uint32_type) { ig.Emit(OpCodes.Ldind_U4); } else if (t == TypeManager.short_type) { ig.Emit(OpCodes.Ldind_I2); } else if (t == TypeManager.ushort_type) { ig.Emit(OpCodes.Ldind_U2); } else if (t == TypeManager.char_type) { ig.Emit(OpCodes.Ldind_U2); } else if (t == TypeManager.byte_type) { ig.Emit(OpCodes.Ldind_U1); } else if (t == TypeManager.sbyte_type) { ig.Emit(OpCodes.Ldind_I1); } else if (t == TypeManager.uint64_type) { ig.Emit(OpCodes.Ldind_I8); } else if (t == TypeManager.int64_type) { ig.Emit(OpCodes.Ldind_I8); } else if (t == TypeManager.float_type) { ig.Emit(OpCodes.Ldind_R4); } else if (t == TypeManager.double_type) { ig.Emit(OpCodes.Ldind_R8); } else if (t == TypeManager.bool_type) { ig.Emit(OpCodes.Ldind_I1); } else if (t == TypeManager.intptr_type) { ig.Emit(OpCodes.Ldind_I); } else if (t.IsEnum) { if (t == TypeManager.enum_type) { ig.Emit(OpCodes.Ldind_Ref); } else { EmitLoadFromPtr(EnumSpec.GetUnderlyingType(t)); } } else if (TypeManager.IsStruct(t) || TypeManager.IsGenericParameter(t)) { Emit(OpCodes.Ldobj, t); } else if (t.IsPointer) { ig.Emit(OpCodes.Ldind_I); } else { ig.Emit(OpCodes.Ldind_Ref); } }
public Constant CreateConstantReference(Location loc) { return(Constant.CreateConstant(TypeManager.TypeToCoreType(fi.FieldType), value, loc)); }
public static string FullDelegateDesc(MethodSpec invoke_method) { return(TypeManager.GetFullNameSignature(invoke_method).Replace(".Invoke", "")); }
void EmitFieldSize(int buffer_size) { int type_size = BuiltinTypeSpec.GetSize(MemberType); if (buffer_size > int.MaxValue / type_size) { Report.Error(1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", GetSignatureForError(), buffer_size.ToString(), TypeManager.CSharpName(MemberType)); return; } AttributeEncoder encoder; var ctor = Module.PredefinedMembers.StructLayoutAttributeCtor.Resolve(Location); if (ctor == null) { return; } var field_size = Module.PredefinedMembers.StructLayoutSize.Resolve(Location); var field_charset = Module.PredefinedMembers.StructLayoutCharSet.Resolve(Location); if (field_size == null || field_charset == null) { return; } var char_set = CharSet ?? Module.DefaultCharSet ?? 0; encoder = new AttributeEncoder(); encoder.Encode((short)LayoutKind.Sequential); encoder.EncodeNamedArguments( new [] { field_size, field_charset }, new Constant [] { new IntConstant(Compiler.BuiltinTypes, buffer_size * type_size, Location), new IntConstant(Compiler.BuiltinTypes, (int)char_set, Location) } ); fixed_buffer_type.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray()); // // Don't emit FixedBufferAttribute attribute for private types // if ((ModFlags & Modifiers.PRIVATE) != 0) { return; } ctor = Module.PredefinedMembers.FixedBufferAttributeCtor.Resolve(Location); if (ctor == null) { return; } encoder = new AttributeEncoder(); encoder.EncodeTypeName(MemberType); encoder.Encode(buffer_size); encoder.EncodeEmptyNamedArguments(); FieldBuilder.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), encoder.ToArray()); }
public void Resolve(ResolveContext rc, Parameter p) { var expr = Resolve(rc); if (expr == null) { return; } expr = Child; if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New)expr).IsDefaultStruct))) { rc.Compiler.Report.Error(1736, Location, "The expression being assigned to optional parameter `{0}' must be a constant or default value", p.Name); return; } var parameter_type = p.Type; if (type == parameter_type) { return; } var res = Convert.ImplicitConversionStandard(rc, expr, parameter_type, Location); if (res != null) { if (TypeManager.IsNullableType(parameter_type) && res is Nullable.Wrap) { Nullable.Wrap wrap = (Nullable.Wrap)res; res = wrap.Child; if (!(res is Constant)) { rc.Compiler.Report.Error(1770, Location, "The expression being assigned to nullable optional parameter `{0}' must be default value", p.Name); return; } } if (!expr.IsNull && TypeManager.IsReferenceType(parameter_type) && parameter_type != TypeManager.string_type) { rc.Compiler.Report.Error(1763, Location, "Optional parameter `{0}' of type `{1}' can only be initialized with `null'", p.Name, parameter_type.GetSignatureForError()); return; } this.expr = res; return; } rc.Compiler.Report.Error(1750, Location, "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'", type.GetSignatureForError(), parameter_type.GetSignatureForError()); }
// // Imports SRE parameters // public static AParametersCollection Create(ParameterInfo [] pi, MethodBase method) { int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0; if (pi.Length == 0 && varargs == 0) { return(ParametersCompiled.EmptyReadOnlyParameters); } Type [] types = new Type [pi.Length + varargs]; IParameterData [] par = new IParameterData [pi.Length + varargs]; bool is_params = false; PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension; PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray; for (int i = 0; i < pi.Length; i++) { types [i] = TypeManager.TypeToCoreType(pi [i].ParameterType); ParameterInfo p = pi [i]; Parameter.Modifier mod = 0; Expression default_value = null; if (types [i].IsByRef) { if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out) { mod = Parameter.Modifier.OUT; } else { mod = Parameter.Modifier.REF; } // // Strip reference wrapping // types [i] = TypeManager.GetElementType(types [i]); } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic && (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute && method.IsDefined(extension_attr.Type, false)) { mod = Parameter.Modifier.This; } else { if (i >= pi.Length - 2 && types[i].IsArray) { if (p.IsDefined(param_attr.Type, false)) { mod = Parameter.Modifier.PARAMS; is_params = true; } } if (!is_params && p.IsOptional) { object value = p.DefaultValue; if (value == Missing.Value) { default_value = EmptyExpression.Null; } else if (value == null) { default_value = new NullLiteral(Location.Null); } else { default_value = Constant.CreateConstant(value.GetType(), value, Location.Null); } } } par [i] = new ParameterData(p.Name, mod, default_value); } if (varargs != 0) { par [par.Length - 1] = new ArglistParameter(Location.Null); types [types.Length - 1] = InternalType.Arglist; } return(method != null ? new ParametersImported(par, types, varargs != 0, is_params) : new ParametersImported(par, types)); }
static CompiledMethod CompileBlock(Class host, Undo undo, Report Report) { RootContext.ResolveTree(); if (Report.Errors != 0) { undo.ExecuteUndo(); return(null); } RootContext.PopulateTypes(); if (Report.Errors != 0) { undo.ExecuteUndo(); return(null); } TypeBuilder tb = null; MethodBuilder mb = null; if (host != null) { tb = host.TypeBuilder; mb = null; foreach (MemberCore member in host.Methods) { if (member.Name != "Host") { continue; } MethodOrOperator method = (MethodOrOperator)member; mb = method.MethodBuilder; break; } if (mb == null) { throw new Exception("Internal error: did not find the method builder for the generated method"); } } RootContext.EmitCode(); if (Report.Errors != 0) { return(null); } RootContext.CloseTypes(); if (Environment.GetEnvironmentVariable("SAVE") != null) { CodeGen.Save(current_debug_name, false, Report); } if (host == null) { return(null); } // // Unlike Mono, .NET requires that the MethodInfo is fetched, it cant // work from MethodBuilders. Retarded, I know. // Type tt = CodeGen.Assembly.Builder.GetType(tb.Name); MethodInfo mi = tt.GetMethod(mb.Name); // Pull the FieldInfos from the type, and keep track of them foreach (Field field in queued_fields) { FieldInfo fi = tt.GetField(field.Name); FieldInfo old = (FieldInfo)fields [field.Name]; // If a previous value was set, nullify it, so that we do // not leak memory if (old != null) { if (TypeManager.IsStruct(old.FieldType)) { // // TODO: Clear fields for structs // } else { try { old.SetValue(null, null); } catch { } } } fields [field.Name] = fi; } //types.Add (tb); queued_fields.Clear(); return((CompiledMethod)System.Delegate.CreateDelegate(typeof(CompiledMethod), mi)); }
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) { Report Report = RootContext.ToplevelTypes.Compiler.Report; if (a.Type == pa.In && ModFlags == Modifier.OUT) { Report.Error(36, a.Location, "An out parameter cannot have the `In' attribute"); return; } if (a.Type == pa.ParamArray) { Report.Error(674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead"); return; } if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF && !OptAttributes.Contains(pa.In)) { Report.Error(662, a.Location, "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither"); return; } if (a.Type == pa.CLSCompliant) { Report.Warning(3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead"); } if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) { Report.Error(1745, a.Location, "Cannot specify `{0}' attribute on optional parameter `{1}'", TypeManager.CSharpName(a.Type).Replace("Attribute", ""), Name); return; } if (a.Type == pa.DefaultParameterValue) { object val = a.GetParameterDefaultValue(); if (val != null) { Type t = val.GetType(); if (t.IsArray || TypeManager.IsSubclassOf(t, TypeManager.type_type)) { if (parameter_type == TypeManager.object_type) { if (!t.IsArray) { t = TypeManager.type_type; } Report.Error(1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute", TypeManager.CSharpName(t)); } else { Report.Error(1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'", TypeManager.CSharpName(parameter_type));; } return; } } if (parameter_type == TypeManager.object_type || (val == null && !TypeManager.IsGenericParameter(parameter_type) && TypeManager.IsReferenceType(parameter_type)) || (val != null && TypeManager.TypeToCoreType(val.GetType()) == parameter_type)) { builder.SetConstant(val); } else { Report.Error(1908, a.Location, "The type of the default value should match the type of the parameter"); } return; } base.ApplyAttributeBuilder(a, cb, pa); }
// // Checks whether the type P is as accessible as this member // public bool IsAccessibleAs(TypeSpec p) { // // if M is private, its accessibility is the same as this declspace. // we already know that P is accessible to T before this method, so we // may return true. // if ((mod_flags & Modifiers.PRIVATE) != 0) { return(true); } while (TypeManager.HasElementType(p)) { p = TypeManager.GetElementType(p); } if (p.IsGenericParameter) { return(true); } for (TypeSpec p_parent; p != null; p = p_parent) { p_parent = p.DeclaringType; if (p.IsGeneric) { foreach (TypeSpec t in p.TypeArguments) { if (!IsAccessibleAs(t)) { return(false); } } } var pAccess = p.Modifiers & Modifiers.AccessibilityMask; if (pAccess == Modifiers.PUBLIC) { continue; } bool same_access_restrictions = false; for (MemberCore mc = this; !same_access_restrictions && mc != null && mc.Parent != null; mc = mc.Parent) { var al = mc.ModFlags & Modifiers.AccessibilityMask; switch (pAccess) { case Modifiers.INTERNAL: if (al == Modifiers.PRIVATE || al == Modifiers.INTERNAL) { same_access_restrictions = p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } break; case Modifiers.PROTECTED: if (al == Modifiers.PROTECTED) { same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent); break; } if (al == Modifiers.PRIVATE) { // // When type is private and any of its parents derives from // protected type then the type is accessible // while (mc.Parent != null && mc.Parent.PartialContainer != null) { if (mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent)) { same_access_restrictions = true; } mc = mc.Parent; } } break; case Modifiers.PROTECTED | Modifiers.INTERNAL: if (al == Modifiers.INTERNAL) { same_access_restrictions = p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL)) { same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent) && p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } else { goto case Modifiers.PROTECTED; } break; case Modifiers.PRIVATE: // // Both are private and share same parent // if (al == Modifiers.PRIVATE) { var decl = mc.Parent; do { same_access_restrictions = decl.CurrentType == p_parent; }while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null); } break; default: throw new InternalErrorException(al.ToString()); } } if (!same_access_restrictions) { return(false); } } return(true); }
/// <summary> /// Check whether `a' and `b' may become equal generic types. /// The algorithm to do that is a little bit complicated. /// </summary> static bool MayBecomeEqualGenericTypes(TypeSpec a, TypeSpec b) { if (a.IsGenericParameter) { // // If a is an array of a's type, they may never // become equal. // if (b.IsArray) { return(false); } // // If b is a generic parameter or an actual type, // they may become equal: // // class X<T,U> : I<T>, I<U> // class X<T> : I<T>, I<float> // if (b.IsGenericParameter) { return(a.DeclaringType == b.DeclaringType); } // // We're now comparing a type parameter with a // generic instance. They may become equal unless // the type parameter appears anywhere in the // generic instance: // // class X<T,U> : I<T>, I<X<U>> // -> error because you could instanciate it as // X<X<int>,int> // // class X<T> : I<T>, I<X<T>> -> ok // return(!ContainsTypeParameter(a, b)); } if (b.IsGenericParameter) { return(MayBecomeEqualGenericTypes(b, a)); } // // At this point, neither a nor b are a type parameter. // // If one of them is a generic instance, compare them (if the // other one is not a generic instance, they can never // become equal). // if (TypeManager.IsGenericType(a) || TypeManager.IsGenericType(b)) { return(IsEqual(a, b)); } // // If both of them are arrays. // var a_ac = a as ArrayContainer; if (a_ac != null) { var b_ac = b as ArrayContainer; if (b_ac == null || a_ac.Rank != b_ac.Rank) { return(false); } return(MayBecomeEqualGenericTypes(a_ac.Element, b_ac.Element)); } // // Ok, two ordinary types. // return(false); }