PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/mcs/attribute.cs

https://bitbucket.org/danipen/mono
C# | 2029 lines | 1523 code | 351 blank | 155 comment | 387 complexity | 70c9fe85afdcc486eba76bfeb31be99d MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // attribute.cs: Attribute Handler
  3. //
  4. // Author: Ravi Pratap (ravi@ximian.com)
  5. // Marek Safar (marek.safar@seznam.cz)
  6. //
  7. // Dual licensed under the terms of the MIT X11 or GNU GPL
  8. //
  9. // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  10. // Copyright 2003-2008 Novell, Inc.
  11. // Copyright 2011 Xamarin Inc
  12. //
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Runtime.InteropServices;
  16. using System.Runtime.CompilerServices;
  17. using System.Security;
  18. using System.Security.Permissions;
  19. using System.Text;
  20. using System.IO;
  21. #if STATIC
  22. using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
  23. using BadImageFormat = IKVM.Reflection.BadImageFormatException;
  24. using IKVM.Reflection;
  25. using IKVM.Reflection.Emit;
  26. #else
  27. using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
  28. using BadImageFormat = System.BadImageFormatException;
  29. using System.Reflection;
  30. using System.Reflection.Emit;
  31. #endif
  32. namespace Mono.CSharp {
  33. /// <summary>
  34. /// Base class for objects that can have Attributes applied to them.
  35. /// </summary>
  36. public abstract class Attributable {
  37. //
  38. // Holds all attributes attached to this element
  39. //
  40. protected Attributes attributes;
  41. public void AddAttributes (Attributes attrs, IMemberContext context)
  42. {
  43. if (attrs == null)
  44. return;
  45. if (attributes == null)
  46. attributes = attrs;
  47. else
  48. attributes.AddAttributes (attrs.Attrs);
  49. attrs.AttachTo (this, context);
  50. }
  51. public Attributes OptAttributes {
  52. get {
  53. return attributes;
  54. }
  55. set {
  56. attributes = value;
  57. }
  58. }
  59. /// <summary>
  60. /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
  61. /// </summary>
  62. public abstract void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa);
  63. /// <summary>
  64. /// Returns one AttributeTarget for this element.
  65. /// </summary>
  66. public abstract AttributeTargets AttributeTargets { get; }
  67. public abstract bool IsClsComplianceRequired ();
  68. /// <summary>
  69. /// Gets list of valid attribute targets for explicit target declaration.
  70. /// The first array item is default target. Don't break this rule.
  71. /// </summary>
  72. public abstract string[] ValidAttributeTargets { get; }
  73. };
  74. public class Attribute
  75. {
  76. public readonly string ExplicitTarget;
  77. public AttributeTargets Target;
  78. readonly ATypeNameExpression expression;
  79. Arguments pos_args, named_args;
  80. bool resolve_error;
  81. bool arg_resolved;
  82. readonly bool nameEscaped;
  83. readonly Location loc;
  84. public TypeSpec Type;
  85. //
  86. // An attribute can be attached to multiple targets (e.g. multiple fields)
  87. //
  88. Attributable[] targets;
  89. //
  90. // A member context for the attribute, it's much easier to hold it here
  91. // than trying to pull it during resolve
  92. //
  93. IMemberContext context;
  94. public static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
  95. public static readonly object[] EmptyObject = new object [0];
  96. List<KeyValuePair<MemberExpr, NamedArgument>> named_values;
  97. public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
  98. {
  99. this.expression = expr;
  100. if (args != null) {
  101. pos_args = args[0];
  102. named_args = args[1];
  103. }
  104. this.loc = loc;
  105. ExplicitTarget = target;
  106. this.nameEscaped = nameEscaped;
  107. }
  108. public Location Location {
  109. get {
  110. return loc;
  111. }
  112. }
  113. public Arguments NamedArguments {
  114. get {
  115. return named_args;
  116. }
  117. }
  118. public Arguments PositionalArguments {
  119. get {
  120. return pos_args;
  121. }
  122. }
  123. public bool ResolveError {
  124. get {
  125. return resolve_error;
  126. }
  127. }
  128. public ATypeNameExpression TypeExpression {
  129. get {
  130. return expression;
  131. }
  132. }
  133. void AddModuleCharSet (ResolveContext rc)
  134. {
  135. const string dll_import_char_set = "CharSet";
  136. //
  137. // Only when not customized by user
  138. //
  139. if (HasField (dll_import_char_set))
  140. return;
  141. if (!rc.Module.PredefinedTypes.CharSet.Define ()) {
  142. return;
  143. }
  144. if (NamedArguments == null)
  145. named_args = new Arguments (1);
  146. var value = Constant.CreateConstantFromValue (rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location);
  147. NamedArguments.Add (new NamedArgument (dll_import_char_set, loc, value));
  148. }
  149. public Attribute Clone ()
  150. {
  151. Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
  152. a.pos_args = pos_args;
  153. a.named_args = NamedArguments;
  154. return a;
  155. }
  156. //
  157. // When the same attribute is attached to multiple fiels
  158. // we use @target field as a list of targets. The attribute
  159. // has to be resolved only once but emitted for each target.
  160. //
  161. public void AttachTo (Attributable target, IMemberContext context)
  162. {
  163. if (this.targets == null) {
  164. this.targets = new Attributable[] { target };
  165. this.context = context;
  166. return;
  167. }
  168. // When re-attaching global attributes
  169. if (context is NamespaceContainer) {
  170. this.targets[0] = target;
  171. this.context = context;
  172. return;
  173. }
  174. // Resize target array
  175. Attributable[] new_array = new Attributable [this.targets.Length + 1];
  176. targets.CopyTo (new_array, 0);
  177. new_array [targets.Length] = target;
  178. this.targets = new_array;
  179. // No need to update context, different targets cannot have
  180. // different contexts, it's enough to remove same attributes
  181. // from secondary members.
  182. target.OptAttributes = null;
  183. }
  184. public ResolveContext CreateResolveContext ()
  185. {
  186. return new ResolveContext (context, ResolveContext.Options.ConstantScope);
  187. }
  188. static void Error_InvalidNamedArgument (ResolveContext rc, NamedArgument name)
  189. {
  190. rc.Report.Error (617, name.Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
  191. "must be fields which are not readonly, static, const or read-write properties which are " +
  192. "public and not static",
  193. name.Name);
  194. }
  195. static void Error_InvalidNamedArgumentType (ResolveContext rc, NamedArgument name)
  196. {
  197. rc.Report.Error (655, name.Location,
  198. "`{0}' is not a valid named attribute argument because it is not a valid attribute parameter type",
  199. name.Name);
  200. }
  201. public static void Error_AttributeArgumentIsDynamic (IMemberContext context, Location loc)
  202. {
  203. context.Module.Compiler.Report.Error (1982, loc, "An attribute argument cannot be dynamic expression");
  204. }
  205. public void Error_MissingGuidAttribute ()
  206. {
  207. Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
  208. }
  209. public void Error_MisusedExtensionAttribute ()
  210. {
  211. Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ());
  212. }
  213. public void Error_MisusedDynamicAttribute ()
  214. {
  215. Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword instead", GetSignatureForError ());
  216. }
  217. /// <summary>
  218. /// This is rather hack. We report many emit attribute error with same error to be compatible with
  219. /// csc. But because csc has to report them this way because error came from ilasm we needn't.
  220. /// </summary>
  221. public void Error_AttributeEmitError (string inner)
  222. {
  223. Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'",
  224. TypeManager.CSharpName (Type), inner);
  225. }
  226. public void Error_InvalidSecurityParent ()
  227. {
  228. Error_AttributeEmitError ("it is attached to invalid parent");
  229. }
  230. Attributable Owner {
  231. get {
  232. return targets [0];
  233. }
  234. }
  235. /// <summary>
  236. /// Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
  237. /// </summary>
  238. void ResolveAttributeType (bool comparisonOnly)
  239. {
  240. SessionReportPrinter resolve_printer = new SessionReportPrinter ();
  241. ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer);
  242. bool t1_is_attr = false;
  243. bool t2_is_attr = false;
  244. TypeSpec t1, t2;
  245. ATypeNameExpression expanded = null;
  246. // TODO: Additional warnings such as CS0436 are swallowed because we don't
  247. // print on success
  248. try {
  249. t1 = expression.ResolveAsType (context);
  250. if (t1 != null)
  251. t1_is_attr = t1.IsAttribute;
  252. resolve_printer.EndSession ();
  253. if (nameEscaped) {
  254. t2 = null;
  255. } else {
  256. expanded = (ATypeNameExpression) expression.Clone (null);
  257. expanded.Name += "Attribute";
  258. t2 = expanded.ResolveAsType (context);
  259. if (t2 != null)
  260. t2_is_attr = t2.IsAttribute;
  261. }
  262. } finally {
  263. context.Module.Compiler.Report.SetPrinter (prev_recorder);
  264. }
  265. if (t1_is_attr && t2_is_attr && t1 != t2) {
  266. if (!comparisonOnly) {
  267. Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
  268. GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
  269. resolve_error = true;
  270. }
  271. return;
  272. }
  273. if (t1_is_attr) {
  274. Type = t1;
  275. return;
  276. }
  277. if (t2_is_attr) {
  278. Type = t2;
  279. return;
  280. }
  281. if (comparisonOnly)
  282. return;
  283. resolve_error = true;
  284. if (t1 != null) {
  285. resolve_printer.Merge (prev_recorder);
  286. Report.SymbolRelatedToPreviousError (t1);
  287. Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
  288. return;
  289. }
  290. if (t2 != null) {
  291. Report.SymbolRelatedToPreviousError (t2);
  292. Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
  293. return;
  294. }
  295. resolve_printer.Merge (prev_recorder);
  296. }
  297. public TypeSpec ResolveTypeForComparison ()
  298. {
  299. if (Type == null && !resolve_error)
  300. ResolveAttributeType (true);
  301. return Type;
  302. }
  303. public string GetSignatureForError ()
  304. {
  305. if (Type != null)
  306. return TypeManager.CSharpName (Type);
  307. return expression.GetSignatureForError ();
  308. }
  309. public bool HasSecurityAttribute {
  310. get {
  311. PredefinedAttribute pa = context.Module.PredefinedAttributes.Security;
  312. return pa.IsDefined && TypeSpec.IsBaseClass (Type, pa.TypeSpec, false);
  313. }
  314. }
  315. public bool IsValidSecurityAttribute ()
  316. {
  317. return HasSecurityAttribute && IsSecurityActionValid ();
  318. }
  319. static bool IsValidArgumentType (TypeSpec t)
  320. {
  321. if (t.IsArray) {
  322. var ac = (ArrayContainer) t;
  323. if (ac.Rank > 1)
  324. return false;
  325. t = ac.Element;
  326. }
  327. switch (t.BuiltinType) {
  328. case BuiltinTypeSpec.Type.Int:
  329. case BuiltinTypeSpec.Type.UInt:
  330. case BuiltinTypeSpec.Type.Long:
  331. case BuiltinTypeSpec.Type.ULong:
  332. case BuiltinTypeSpec.Type.Float:
  333. case BuiltinTypeSpec.Type.Double:
  334. case BuiltinTypeSpec.Type.Char:
  335. case BuiltinTypeSpec.Type.Short:
  336. case BuiltinTypeSpec.Type.Bool:
  337. case BuiltinTypeSpec.Type.SByte:
  338. case BuiltinTypeSpec.Type.Byte:
  339. case BuiltinTypeSpec.Type.UShort:
  340. case BuiltinTypeSpec.Type.String:
  341. case BuiltinTypeSpec.Type.Object:
  342. case BuiltinTypeSpec.Type.Dynamic:
  343. case BuiltinTypeSpec.Type.Type:
  344. return true;
  345. }
  346. return t.IsEnum;
  347. }
  348. // TODO: Don't use this ambiguous value
  349. public string Name {
  350. get { return expression.Name; }
  351. }
  352. public Report Report {
  353. get { return context.Module.Compiler.Report; }
  354. }
  355. public MethodSpec Resolve ()
  356. {
  357. if (resolve_error)
  358. return null;
  359. resolve_error = true;
  360. arg_resolved = true;
  361. if (Type == null) {
  362. ResolveAttributeType (false);
  363. if (Type == null)
  364. return null;
  365. }
  366. if (Type.IsAbstract) {
  367. Report.Error (653, Location, "Cannot apply attribute class `{0}' because it is abstract", GetSignatureForError ());
  368. return null;
  369. }
  370. ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
  371. if (obsolete_attr != null) {
  372. AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
  373. }
  374. ResolveContext rc = null;
  375. MethodSpec ctor;
  376. // Try if the attribute is simple and has been resolved before
  377. if (pos_args != null || !context.Module.AttributeConstructorCache.TryGetValue (Type, out ctor)) {
  378. rc = CreateResolveContext ();
  379. ctor = ResolveConstructor (rc);
  380. if (ctor == null) {
  381. return null;
  382. }
  383. if (pos_args == null && ctor.Parameters.IsEmpty)
  384. context.Module.AttributeConstructorCache.Add (Type, ctor);
  385. }
  386. //
  387. // Add [module: DefaultCharSet] to all DllImport import attributes
  388. //
  389. var module = context.Module;
  390. if ((Type == module.PredefinedAttributes.DllImport || Type == module.PredefinedAttributes.UnmanagedFunctionPointer) && module.HasDefaultCharSet) {
  391. if (rc == null)
  392. rc = CreateResolveContext ();
  393. AddModuleCharSet (rc);
  394. }
  395. if (NamedArguments != null) {
  396. if (rc == null)
  397. rc = CreateResolveContext ();
  398. if (!ResolveNamedArguments (rc))
  399. return null;
  400. }
  401. resolve_error = false;
  402. return ctor;
  403. }
  404. MethodSpec ResolveConstructor (ResolveContext ec)
  405. {
  406. if (pos_args != null) {
  407. bool dynamic;
  408. pos_args.Resolve (ec, out dynamic);
  409. if (dynamic) {
  410. Error_AttributeArgumentIsDynamic (ec.MemberContext, loc);
  411. return null;
  412. }
  413. }
  414. return Expression.ConstructorLookup (ec, Type, ref pos_args, loc);
  415. }
  416. bool ResolveNamedArguments (ResolveContext ec)
  417. {
  418. int named_arg_count = NamedArguments.Count;
  419. var seen_names = new List<string> (named_arg_count);
  420. named_values = new List<KeyValuePair<MemberExpr, NamedArgument>> (named_arg_count);
  421. foreach (NamedArgument a in NamedArguments) {
  422. string name = a.Name;
  423. if (seen_names.Contains (name)) {
  424. ec.Report.Error (643, a.Location, "Duplicate named attribute `{0}' argument", name);
  425. continue;
  426. }
  427. seen_names.Add (name);
  428. a.Resolve (ec);
  429. Expression member = Expression.MemberLookup (ec, false, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
  430. if (member == null) {
  431. member = Expression.MemberLookup (ec, true, Type, name, 0, Expression.MemberLookupRestrictions.ExactArity, loc);
  432. if (member != null) {
  433. // TODO: ec.Report.SymbolRelatedToPreviousError (member);
  434. Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
  435. return false;
  436. }
  437. }
  438. if (member == null){
  439. Expression.Error_TypeDoesNotContainDefinition (ec, Location, Type, name);
  440. return false;
  441. }
  442. if (!(member is PropertyExpr || member is FieldExpr)) {
  443. Error_InvalidNamedArgument (ec, a);
  444. return false;
  445. }
  446. ObsoleteAttribute obsolete_attr;
  447. if (member is PropertyExpr) {
  448. var pi = ((PropertyExpr) member).PropertyInfo;
  449. if (!pi.HasSet || !pi.HasGet || pi.IsStatic || !pi.Get.IsPublic || !pi.Set.IsPublic) {
  450. ec.Report.SymbolRelatedToPreviousError (pi);
  451. Error_InvalidNamedArgument (ec, a);
  452. return false;
  453. }
  454. if (!IsValidArgumentType (member.Type)) {
  455. ec.Report.SymbolRelatedToPreviousError (pi);
  456. Error_InvalidNamedArgumentType (ec, a);
  457. return false;
  458. }
  459. obsolete_attr = pi.GetAttributeObsolete ();
  460. pi.MemberDefinition.SetIsAssigned ();
  461. } else {
  462. var fi = ((FieldExpr) member).Spec;
  463. if (fi.IsReadOnly || fi.IsStatic || !fi.IsPublic) {
  464. Error_InvalidNamedArgument (ec, a);
  465. return false;
  466. }
  467. if (!IsValidArgumentType (member.Type)) {
  468. ec.Report.SymbolRelatedToPreviousError (fi);
  469. Error_InvalidNamedArgumentType (ec, a);
  470. return false;
  471. }
  472. obsolete_attr = fi.GetAttributeObsolete ();
  473. fi.MemberDefinition.SetIsAssigned ();
  474. }
  475. if (obsolete_attr != null && !context.IsObsolete)
  476. AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location, Report);
  477. if (a.Type != member.Type) {
  478. a.Expr = Convert.ImplicitConversionRequired (ec, a.Expr, member.Type, a.Expr.Location);
  479. }
  480. if (a.Expr != null)
  481. named_values.Add (new KeyValuePair<MemberExpr, NamedArgument> ((MemberExpr) member, a));
  482. }
  483. return true;
  484. }
  485. /// <summary>
  486. /// Get a string containing a list of valid targets for the attribute 'attr'
  487. /// </summary>
  488. public string GetValidTargets ()
  489. {
  490. StringBuilder sb = new StringBuilder ();
  491. AttributeTargets targets = Type.GetAttributeUsage (context.Module.PredefinedAttributes.AttributeUsage).ValidOn;
  492. if ((targets & AttributeTargets.Assembly) != 0)
  493. sb.Append ("assembly, ");
  494. if ((targets & AttributeTargets.Module) != 0)
  495. sb.Append ("module, ");
  496. if ((targets & AttributeTargets.Class) != 0)
  497. sb.Append ("class, ");
  498. if ((targets & AttributeTargets.Struct) != 0)
  499. sb.Append ("struct, ");
  500. if ((targets & AttributeTargets.Enum) != 0)
  501. sb.Append ("enum, ");
  502. if ((targets & AttributeTargets.Constructor) != 0)
  503. sb.Append ("constructor, ");
  504. if ((targets & AttributeTargets.Method) != 0)
  505. sb.Append ("method, ");
  506. if ((targets & AttributeTargets.Property) != 0)
  507. sb.Append ("property, indexer, ");
  508. if ((targets & AttributeTargets.Field) != 0)
  509. sb.Append ("field, ");
  510. if ((targets & AttributeTargets.Event) != 0)
  511. sb.Append ("event, ");
  512. if ((targets & AttributeTargets.Interface) != 0)
  513. sb.Append ("interface, ");
  514. if ((targets & AttributeTargets.Parameter) != 0)
  515. sb.Append ("parameter, ");
  516. if ((targets & AttributeTargets.Delegate) != 0)
  517. sb.Append ("delegate, ");
  518. if ((targets & AttributeTargets.ReturnValue) != 0)
  519. sb.Append ("return, ");
  520. if ((targets & AttributeTargets.GenericParameter) != 0)
  521. sb.Append ("type parameter, ");
  522. return sb.Remove (sb.Length - 2, 2).ToString ();
  523. }
  524. public AttributeUsageAttribute GetAttributeUsageAttribute ()
  525. {
  526. if (!arg_resolved)
  527. // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
  528. // But because a lot of attribute class code must be rewritten will be better to wait...
  529. Resolve ();
  530. if (resolve_error)
  531. return DefaultUsageAttribute;
  532. AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets) ((Constant) pos_args[0].Expr).GetValue ());
  533. var field = GetNamedValue ("AllowMultiple") as BoolConstant;
  534. if (field != null)
  535. usage_attribute.AllowMultiple = field.Value;
  536. field = GetNamedValue ("Inherited") as BoolConstant;
  537. if (field != null)
  538. usage_attribute.Inherited = field.Value;
  539. return usage_attribute;
  540. }
  541. /// <summary>
  542. /// Returns custom name of indexer
  543. /// </summary>
  544. public string GetIndexerAttributeValue ()
  545. {
  546. if (!arg_resolved)
  547. // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
  548. // But because a lot of attribute class code must be rewritten will be better to wait...
  549. Resolve ();
  550. if (resolve_error || pos_args.Count != 1 || !(pos_args[0].Expr is Constant))
  551. return null;
  552. return ((Constant) pos_args[0].Expr).GetValue () as string;
  553. }
  554. /// <summary>
  555. /// Returns condition of ConditionalAttribute
  556. /// </summary>
  557. public string GetConditionalAttributeValue ()
  558. {
  559. if (!arg_resolved)
  560. // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
  561. // But because a lot of attribute class code must be rewritten will be better to wait...
  562. Resolve ();
  563. if (resolve_error)
  564. return null;
  565. return ((Constant) pos_args[0].Expr).GetValue () as string;
  566. }
  567. /// <summary>
  568. /// Creates the instance of ObsoleteAttribute from this attribute instance
  569. /// </summary>
  570. public ObsoleteAttribute GetObsoleteAttribute ()
  571. {
  572. if (!arg_resolved) {
  573. // corlib only case when obsolete is used before is resolved
  574. var c = Type.MemberDefinition as Class;
  575. if (c != null && !c.HasMembersDefined)
  576. c.Define ();
  577. // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
  578. // But because a lot of attribute class code must be rewritten will be better to wait...
  579. Resolve ();
  580. }
  581. if (resolve_error)
  582. return null;
  583. if (pos_args == null)
  584. return new ObsoleteAttribute ();
  585. string msg = ((Constant) pos_args[0].Expr).GetValue () as string;
  586. if (pos_args.Count == 1)
  587. return new ObsoleteAttribute (msg);
  588. return new ObsoleteAttribute (msg, ((BoolConstant) pos_args[1].Expr).Value);
  589. }
  590. /// <summary>
  591. /// Returns value of CLSCompliantAttribute contructor parameter but because the method can be called
  592. /// before ApplyAttribute. We need to resolve the arguments.
  593. /// This situation occurs when class deps is differs from Emit order.
  594. /// </summary>
  595. public bool GetClsCompliantAttributeValue ()
  596. {
  597. if (!arg_resolved)
  598. // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
  599. // But because a lot of attribute class code must be rewritten will be better to wait...
  600. Resolve ();
  601. if (resolve_error)
  602. return false;
  603. return ((BoolConstant) pos_args[0].Expr).Value;
  604. }
  605. public TypeSpec GetCoClassAttributeValue ()
  606. {
  607. if (!arg_resolved)
  608. Resolve ();
  609. if (resolve_error)
  610. return null;
  611. return GetArgumentType ();
  612. }
  613. public bool CheckTarget ()
  614. {
  615. string[] valid_targets = Owner.ValidAttributeTargets;
  616. if (ExplicitTarget == null || ExplicitTarget == valid_targets [0]) {
  617. Target = Owner.AttributeTargets;
  618. return true;
  619. }
  620. // TODO: we can skip the first item
  621. if (Array.Exists (valid_targets, i => i == ExplicitTarget)) {
  622. switch (ExplicitTarget) {
  623. case "return": Target = AttributeTargets.ReturnValue; return true;
  624. case "param": Target = AttributeTargets.Parameter; return true;
  625. case "field": Target = AttributeTargets.Field; return true;
  626. case "method": Target = AttributeTargets.Method; return true;
  627. case "property": Target = AttributeTargets.Property; return true;
  628. case "module": Target = AttributeTargets.Module; return true;
  629. }
  630. throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
  631. }
  632. StringBuilder sb = new StringBuilder ();
  633. foreach (string s in valid_targets) {
  634. sb.Append (s);
  635. sb.Append (", ");
  636. }
  637. sb.Remove (sb.Length - 2, 2);
  638. Report.Warning (657, 1, Location,
  639. "`{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are `{1}'. All attributes in this section will be ignored",
  640. ExplicitTarget, sb.ToString ());
  641. return false;
  642. }
  643. /// <summary>
  644. /// Tests permitted SecurityAction for assembly or other types
  645. /// </summary>
  646. bool IsSecurityActionValid ()
  647. {
  648. SecurityAction action = GetSecurityActionValue ();
  649. bool for_assembly = Target == AttributeTargets.Assembly || Target == AttributeTargets.Module;
  650. switch (action) {
  651. #pragma warning disable 618
  652. case SecurityAction.Demand:
  653. case SecurityAction.Assert:
  654. case SecurityAction.Deny:
  655. case SecurityAction.PermitOnly:
  656. case SecurityAction.LinkDemand:
  657. case SecurityAction.InheritanceDemand:
  658. if (!for_assembly)
  659. return true;
  660. break;
  661. case SecurityAction.RequestMinimum:
  662. case SecurityAction.RequestOptional:
  663. case SecurityAction.RequestRefuse:
  664. if (for_assembly)
  665. return true;
  666. break;
  667. #pragma warning restore 618
  668. default:
  669. Error_AttributeEmitError ("SecurityAction is out of range");
  670. return false;
  671. }
  672. Error_AttributeEmitError (String.Concat ("SecurityAction `", action, "' is not valid for this declaration"));
  673. return false;
  674. }
  675. System.Security.Permissions.SecurityAction GetSecurityActionValue ()
  676. {
  677. return (SecurityAction) ((Constant) pos_args[0].Expr).GetValue ();
  678. }
  679. /// <summary>
  680. /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table.
  681. /// </summary>
  682. /// <returns></returns>
  683. public void ExtractSecurityPermissionSet (MethodSpec ctor, ref SecurityType permissions)
  684. {
  685. #if STATIC
  686. object[] values = new object[pos_args.Count];
  687. for (int i = 0; i < values.Length; ++i)
  688. values[i] = ((Constant) pos_args[i].Expr).GetValue ();
  689. PropertyInfo[] prop;
  690. object[] prop_values;
  691. if (named_values == null) {
  692. prop = null;
  693. prop_values = null;
  694. } else {
  695. prop = new PropertyInfo[named_values.Count];
  696. prop_values = new object [named_values.Count];
  697. for (int i = 0; i < prop.Length; ++i) {
  698. prop [i] = ((PropertyExpr) named_values [i].Key).PropertyInfo.MetaInfo;
  699. prop_values [i] = ((Constant) named_values [i].Value.Expr).GetValue ();
  700. }
  701. }
  702. if (permissions == null)
  703. permissions = new SecurityType ();
  704. var cab = new CustomAttributeBuilder ((ConstructorInfo) ctor.GetMetaInfo (), values, prop, prop_values);
  705. permissions.Add (cab);
  706. #else
  707. throw new NotSupportedException ();
  708. #endif
  709. }
  710. public Constant GetNamedValue (string name)
  711. {
  712. if (named_values == null)
  713. return null;
  714. for (int i = 0; i < named_values.Count; ++i) {
  715. if (named_values [i].Value.Name == name)
  716. return named_values [i].Value.Expr as Constant;
  717. }
  718. return null;
  719. }
  720. public CharSet GetCharSetValue ()
  721. {
  722. return (CharSet) System.Enum.Parse (typeof (CharSet), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
  723. }
  724. public bool HasField (string fieldName)
  725. {
  726. if (named_values == null)
  727. return false;
  728. foreach (var na in named_values) {
  729. if (na.Value.Name == fieldName)
  730. return true;
  731. }
  732. return false;
  733. }
  734. //
  735. // Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
  736. //
  737. public bool IsInternalCall ()
  738. {
  739. return (GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0;
  740. }
  741. public MethodImplOptions GetMethodImplOptions ()
  742. {
  743. MethodImplOptions options = 0;
  744. if (pos_args.Count == 1) {
  745. options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
  746. } else if (HasField ("Value")) {
  747. var named = GetNamedValue ("Value");
  748. options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
  749. }
  750. return options;
  751. }
  752. //
  753. // Returns true for StructLayoutAttribute with LayoutKind.Explicit value
  754. //
  755. public bool IsExplicitLayoutKind ()
  756. {
  757. if (pos_args == null || pos_args.Count != 1)
  758. return false;
  759. var value = (LayoutKind) System.Enum.Parse (typeof (LayoutKind), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
  760. return value == LayoutKind.Explicit;
  761. }
  762. public Expression GetParameterDefaultValue ()
  763. {
  764. if (pos_args == null)
  765. return null;
  766. return pos_args[0].Expr;
  767. }
  768. public override bool Equals (object obj)
  769. {
  770. Attribute a = obj as Attribute;
  771. if (a == null)
  772. return false;
  773. return Type == a.Type && Target == a.Target;
  774. }
  775. public override int GetHashCode ()
  776. {
  777. return Type.GetHashCode () ^ Target.GetHashCode ();
  778. }
  779. /// <summary>
  780. /// Emit attribute for Attributable symbol
  781. /// </summary>
  782. public void Emit (Dictionary<Attribute, List<Attribute>> allEmitted)
  783. {
  784. var ctor = Resolve ();
  785. if (ctor == null)
  786. return;
  787. var predefined = context.Module.PredefinedAttributes;
  788. AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (predefined.AttributeUsage);
  789. if ((usage_attr.ValidOn & Target) == 0) {
  790. Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
  791. "It is valid on `{1}' declarations only",
  792. GetSignatureForError (), GetValidTargets ());
  793. return;
  794. }
  795. byte[] cdata;
  796. if (pos_args == null && named_values == null) {
  797. cdata = AttributeEncoder.Empty;
  798. } else {
  799. AttributeEncoder encoder = new AttributeEncoder ();
  800. if (pos_args != null) {
  801. var param_types = ctor.Parameters.Types;
  802. for (int j = 0; j < pos_args.Count; ++j) {
  803. var pt = param_types[j];
  804. var arg_expr = pos_args[j].Expr;
  805. if (j == 0) {
  806. if ((Type == predefined.IndexerName || Type == predefined.Conditional) && arg_expr is Constant) {
  807. string v = ((Constant) arg_expr).GetValue () as string;
  808. if (!Tokenizer.IsValidIdentifier (v) || (Type == predefined.IndexerName && Tokenizer.IsKeyword (v))) {
  809. context.Module.Compiler.Report.Error (633, arg_expr.Location,
  810. "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
  811. return;
  812. }
  813. } else if (Type == predefined.Guid) {
  814. try {
  815. string v = ((StringConstant) arg_expr).Value;
  816. new Guid (v);
  817. } catch (Exception e) {
  818. Error_AttributeEmitError (e.Message);
  819. return;
  820. }
  821. } else if (Type == predefined.AttributeUsage) {
  822. int v = ((IntConstant) ((EnumConstant) arg_expr).Child).Value;
  823. if (v == 0) {
  824. context.Module.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute",
  825. "System.AttributeUsage");
  826. }
  827. } else if (Type == predefined.MarshalAs) {
  828. if (pos_args.Count == 1) {
  829. var u_type = (UnmanagedType) System.Enum.Parse (typeof (UnmanagedType), ((Constant) pos_args[0].Expr).GetValue ().ToString ());
  830. if (u_type == UnmanagedType.ByValArray && !(Owner is FieldBase)) {
  831. Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
  832. }
  833. }
  834. } else if (Type == predefined.DllImport) {
  835. if (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
  836. var value = ((Constant) pos_args[0].Expr).GetValue () as string;
  837. if (string.IsNullOrEmpty (value))
  838. Error_AttributeEmitError ("DllName cannot be empty or null");
  839. }
  840. } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
  841. !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
  842. Error_AttributeEmitError ("Incorrect argument value.");
  843. return;
  844. }
  845. }
  846. arg_expr.EncodeAttributeValue (context, encoder, pt);
  847. }
  848. }
  849. if (named_values != null) {
  850. encoder.Encode ((ushort) named_values.Count);
  851. foreach (var na in named_values) {
  852. if (na.Key is FieldExpr)
  853. encoder.Encode ((byte) 0x53);
  854. else
  855. encoder.Encode ((byte) 0x54);
  856. encoder.Encode (na.Key.Type);
  857. encoder.Encode (na.Value.Name);
  858. na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type);
  859. }
  860. } else {
  861. encoder.EncodeEmptyNamedArguments ();
  862. }
  863. cdata = encoder.ToArray ();
  864. }
  865. if (!ctor.DeclaringType.IsConditionallyExcluded (context, Location)) {
  866. try {
  867. foreach (Attributable target in targets)
  868. target.ApplyAttributeBuilder (this, ctor, cdata, predefined);
  869. } catch (Exception e) {
  870. if (e is BadImageFormat && Report.Errors > 0)
  871. return;
  872. Error_AttributeEmitError (e.Message);
  873. return;
  874. }
  875. }
  876. if (!usage_attr.AllowMultiple && allEmitted != null) {
  877. if (allEmitted.ContainsKey (this)) {
  878. var a = allEmitted [this];
  879. if (a == null) {
  880. a = new List<Attribute> (2);
  881. allEmitted [this] = a;
  882. }
  883. a.Add (this);
  884. } else {
  885. allEmitted.Add (this, null);
  886. }
  887. }
  888. if (!context.Module.Compiler.Settings.VerifyClsCompliance)
  889. return;
  890. // Here we are testing attribute arguments for array usage (error 3016)
  891. if (Owner.IsClsComplianceRequired ()) {
  892. if (pos_args != null)
  893. pos_args.CheckArrayAsAttribute (context.Module.Compiler);
  894. if (NamedArguments == null)
  895. return;
  896. NamedArguments.CheckArrayAsAttribute (context.Module.Compiler);
  897. }
  898. }
  899. private Expression GetValue ()
  900. {
  901. if (pos_args == null || pos_args.Count < 1)
  902. return null;
  903. return pos_args[0].Expr;
  904. }
  905. public string GetString ()
  906. {
  907. Expression e = GetValue ();
  908. if (e is StringConstant)
  909. return ((StringConstant)e).Value;
  910. return null;
  911. }
  912. public bool GetBoolean ()
  913. {
  914. Expression e = GetValue ();
  915. if (e is BoolConstant)
  916. return ((BoolConstant)e).Value;
  917. return false;
  918. }
  919. public TypeSpec GetArgumentType ()
  920. {
  921. TypeOf e = GetValue () as TypeOf;
  922. if (e == null)
  923. return null;
  924. return e.TypeArgument;
  925. }
  926. }
  927. public class Attributes
  928. {
  929. public readonly List<Attribute> Attrs;
  930. public Attributes (Attribute a)
  931. {
  932. Attrs = new List<Attribute> ();
  933. Attrs.Add (a);
  934. }
  935. public Attributes (List<Attribute> attrs)
  936. {
  937. Attrs = attrs;
  938. }
  939. public void AddAttribute (Attribute attr)
  940. {
  941. Attrs.Add (attr);
  942. }
  943. public void AddAttributes (List<Attribute> attrs)
  944. {
  945. Attrs.AddRange (attrs);
  946. }
  947. public void AttachTo (Attributable attributable, IMemberContext context)
  948. {
  949. foreach (Attribute a in Attrs)
  950. a.AttachTo (attributable, context);
  951. }
  952. public Attributes Clone ()
  953. {
  954. var al = new List<Attribute> (Attrs.Count);
  955. foreach (Attribute a in Attrs)
  956. al.Add (a.Clone ());
  957. return new Attributes (al);
  958. }
  959. /// <summary>
  960. /// Checks whether attribute target is valid for the current element
  961. /// </summary>
  962. public bool CheckTargets ()
  963. {
  964. for (int i = 0; i < Attrs.Count; ++i) {
  965. if (!Attrs [i].CheckTarget ())
  966. Attrs.RemoveAt (i--);
  967. }
  968. return true;
  969. }
  970. public void ConvertGlobalAttributes (TypeContainer member, NamespaceContainer currentNamespace, bool isGlobal)
  971. {
  972. var member_explicit_targets = member.ValidAttributeTargets;
  973. for (int i = 0; i < Attrs.Count; ++i) {
  974. var attr = Attrs[0];
  975. if (attr.ExplicitTarget == null)
  976. continue;
  977. int ii;
  978. for (ii = 0; ii < member_explicit_targets.Length; ++ii) {
  979. if (attr.ExplicitTarget == member_explicit_targets[ii]) {
  980. ii = -1;
  981. break;
  982. }
  983. }
  984. if (ii < 0 || !isGlobal)
  985. continue;
  986. member.Module.AddAttribute (attr, currentNamespace);
  987. Attrs.RemoveAt (i);
  988. --i;
  989. }
  990. }
  991. public bool HasResolveError()
  992. {
  993. foreach (var a in Attrs) {
  994. if (a.ResolveError)
  995. return true;
  996. }
  997. return false;
  998. }
  999. public Attribute Search (PredefinedAttribute t)
  1000. {
  1001. return Search (null, t);
  1002. }
  1003. public Attribute Search (string explicitTarget, PredefinedAttribute t)
  1004. {
  1005. foreach (Attribute a in Attrs) {
  1006. if (explicitTarget != null && a.ExplicitTarget != explicitTarget)
  1007. continue;
  1008. if (a.ResolveTypeForComparison () == t)
  1009. return a;
  1010. }
  1011. return null;
  1012. }
  1013. /// <summary>
  1014. /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
  1015. /// </summary>
  1016. public Attribute[] SearchMulti (PredefinedAttribute t)
  1017. {
  1018. List<Attribute> ar = null;
  1019. foreach (Attribute a in Attrs) {
  1020. if (a.ResolveTypeForComparison () == t) {
  1021. if (ar == null)
  1022. ar = new List<Attribute> (Attrs.Count);
  1023. ar.Add (a);
  1024. }
  1025. }
  1026. return ar == null ? null : ar.ToArray ();
  1027. }
  1028. public void Emit ()
  1029. {
  1030. CheckTargets ();
  1031. Dictionary<Attribute, List<Attribute>> ld = Attrs.Count > 1 ? new Dictionary<Attribute, List<Attribute>> () : null;
  1032. foreach (Attribute a in Attrs)
  1033. a.Emit (ld);
  1034. if (ld == null || ld.Count == 0)
  1035. return;
  1036. foreach (var d in ld) {
  1037. if (d.Value == null)
  1038. continue;
  1039. Attribute a = d.Key;
  1040. foreach (Attribute collision in d.Value)
  1041. a.Report.SymbolRelatedToPreviousError (collision.Location, "");
  1042. a.Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times",
  1043. a.GetSignatureForError ());
  1044. }
  1045. }
  1046. public bool Contains (PredefinedAttribute t)
  1047. {
  1048. return Search (t) != null;
  1049. }
  1050. }
  1051. public sealed class AttributeEncoder
  1052. {
  1053. [Flags]
  1054. public enum EncodedTypeProperties
  1055. {
  1056. None = 0,
  1057. DynamicType = 1,
  1058. TypeParameter = 1 << 1
  1059. }
  1060. public static readonly byte[] Empty;
  1061. byte[] buffer;
  1062. int pos;
  1063. const ushort Version = 1;
  1064. static AttributeEncoder ()
  1065. {
  1066. Empty = new byte[4];
  1067. Empty[0] = (byte) Version;
  1068. }
  1069. public AttributeEncoder ()
  1070. {
  1071. buffer = new byte[32];
  1072. Encode (Version);
  1073. }
  1074. public void Encode (bool value)
  1075. {
  1076. Encode (value ? (byte) 1 : (byte) 0);
  1077. }
  1078. public void Encode (byte value)
  1079. {
  1080. if (pos == buffer.Length)
  1081. Grow (1);
  1082. buffer [pos++] = value;
  1083. }
  1084. public void Encode (sbyte value)
  1085. {
  1086. Encode ((byte) value);
  1087. }
  1088. public void Encode (short value)
  1089. {
  1090. if (pos + 2 > buffer.Length)
  1091. Grow (2);
  1092. buffer[pos++] = (byte) value;
  1093. buffer[pos++] = (byte) (value >> 8);
  1094. }
  1095. public void Encode (ushort value)
  1096. {
  1097. Encode ((short) value);
  1098. }
  1099. public void Encode (int value)
  1100. {
  1101. if (pos + 4 > buffer.Length)
  1102. Grow (4);
  1103. buffer[pos++] = (byte) value;
  1104. buffer[pos++] = (byte) (value >> 8);
  1105. buffer[pos++] = (byte) (value >> 16);
  1106. buffer[pos++] = (byte) (value >> 24);
  1107. }
  1108. public void Encode (uint value)
  1109. {
  1110. Encode ((int) value);
  1111. }
  1112. public void Encode (long value)
  1113. {
  1114. if (pos + 8 > buffer.Length)
  1115. Grow (8);
  1116. buffer[pos++] = (byte) value;
  1117. buffer[pos++] = (byte) (value >> 8);
  1118. buffer[pos++] = (byte) (value >> 16);
  1119. buffer[pos++] = (byte) (value >> 24);
  1120. buffer[pos++] = (byte) (value >> 32);
  1121. buffer[pos++] = (byte) (value >> 40);
  1122. buffer[pos++] = (byte) (value >> 48);
  1123. buffer[pos++] = (byte) (value >> 56);
  1124. }
  1125. public void Encode (ulong value)
  1126. {
  1127. Encode ((long) value);
  1128. }
  1129. public void Encode (float value)
  1130. {
  1131. Encode (SingleConverter.SingleToInt32Bits (value));
  1132. }
  1133. public void Encode (double value)
  1134. {
  1135. Encode (BitConverter.DoubleToInt64Bits (value));
  1136. }
  1137. public void Encode (string value)
  1138. {
  1139. if (value == null) {
  1140. Encode ((byte) 0xFF);
  1141. return;
  1142. }
  1143. var buf = Encoding.UTF8.GetBytes(value);
  1144. WriteCompressedValue (buf.Length);
  1145. if (pos + buf.Length > buffer.Length)
  1146. Grow (buf.Length);
  1147. Buffer.BlockCopy (buf, 0, buffer, pos, buf.Length);
  1148. pos += buf.Length;
  1149. }
  1150. public EncodedTypeProperties Encode (TypeSpec type)
  1151. {
  1152. switch (type.BuiltinType) {
  1153. case BuiltinTypeSpec.Type.Bool:
  1154. Encode ((byte) 0x02);
  1155. break;
  1156. case BuiltinTypeSpec.Type.Char:
  1157. Encode ((byte) 0x03);
  1158. break;
  1159. case BuiltinTypeSpec.Type.SByte:
  1160. Encode ((byte) 0x04);
  1161. break;
  1162. case BuiltinTypeSpec.Type.Byte:
  1163. Encode ((byte) 0x05);
  1164. break;
  1165. case BuiltinTypeSpec.Type.Short:
  1166. Encode ((byte) 0x06);
  1167. break;
  1168. case BuiltinTypeSpec.Type.UShort:
  1169. Encode ((byte) 0x07);
  1170. break;
  1171. case BuiltinTypeSpec.Type.Int:
  1172. Encode ((byte) 0x08);
  1173. break;
  1174. case BuiltinTypeSpec.Type.UInt:
  1175. Encode ((byte) 0x09);
  1176. break;
  1177. case BuiltinTypeSpec.Type.Long:
  1178. Encode ((byte) 0x0A);
  1179. break;
  1180. case BuiltinTypeSpec.Type.ULong:
  1181. Encode ((byte) 0x0B);
  1182. break;
  1183. case BuiltinTypeSpec.Type.Float:
  1184. Encode ((byte) 0x0C);
  1185. break;
  1186. case BuiltinTypeSpec.Type.Double:
  1187. Encode ((byte) 0x0D);
  1188. break;
  1189. case BuiltinTypeSpec.Type.String:
  1190. Encode ((byte) 0x0E);
  1191. break;
  1192. case BuiltinTypeSpec.Type.Type:
  1193. Encode ((byte) 0x50);
  1194. break;
  1195. case BuiltinTypeSpec.Type.Object:
  1196. Encode ((byte) 0x51);
  1197. break;
  1198. case BuiltinTypeSpec.Type.Dynamic:
  1199. Encode ((byte) 0x51);
  1200. return EncodedTypeProperties.DynamicType;
  1201. default:
  1202. if (type.IsArray) {
  1203. Encode ((byte) 0x1D);
  1204. return Encode (TypeManager.GetElementType (type));
  1205. }
  1206. if (type.Kind == MemberKind.Enum) {
  1207. Encode ((byte) 0x55);
  1208. EncodeTypeName (type);
  1209. }
  1210. break;
  1211. }
  1212. return EncodedTypeProperties.None;
  1213. }
  1214. public void EncodeTypeName (TypeSpec type)
  1215. {
  1216. var old_type = type.GetMetaInfo ();
  1217. Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
  1218. }
  1219. public void EncodeTypeName (TypeContainer type)
  1220. {
  1221. Encode (type.GetSignatureForMetadata ());
  1222. }
  1223. //
  1224. // Encodes single property named argument per call
  1225. //
  1226. public void EncodeNamedPropertyArgument (PropertySpec property, Constant value)
  1227. {
  1228. Encode ((ushort) 1); // length
  1229. Encode ((byte) 0x54); // property
  1230. Encode (property.MemberType);
  1231. Encode (property.Name);
  1232. value.EncodeAttributeValue (null, this, property.MemberType);
  1233. }
  1234. //
  1235. // Encodes single field named argument per call
  1236. //
  1237. public void EncodeNamedFieldArgument (FieldSpec field, Constant value)
  1238. {
  1239. Encode ((ushort) 1); // length
  1240. Encode ((byte) 0x53); // field
  1241. Encode (field.MemberType);
  1242. Encode (field.Name);
  1243. value.EncodeAttributeValue (null, this, field.MemberType);
  1244. }
  1245. public void EncodeNamedArguments<T> (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec
  1246. {
  1247. Encode ((ushort) members.Length);
  1248. for (int i = 0; i < members.Length; ++i)
  1249. {
  1250. var member = members[i];
  1251. if (member.Kind == MemberKind.Field)
  1252. Encode ((byte) 0x53);
  1253. else if (member.Kind == MemberKind.Property)
  1254. Encode ((byte) 0x54);
  1255. else
  1256. throw new NotImplementedException (member.Kind.ToString ());
  1257. Encode (member.MemberType);
  1258. Encode (member.Name);
  1259. values [i].EncodeAttributeValue (null, this, member.MemberType);
  1260. }
  1261. }
  1262. public void EncodeEmptyNamedArguments ()
  1263. {
  1264. Encode ((ushort) 0);
  1265. }
  1266. void Grow (int inc)
  1267. {
  1268. int size = System.Math.Max (pos * 4, pos + inc + 2);
  1269. Array.Resize (ref buffer, size);
  1270. }
  1271. void WriteCompressedValue (int value)
  1272. {
  1273. if (value < 0x80) {
  1274. Encode ((byte) value);
  1275. return;
  1276. }
  1277. if (value < 0x4000) {
  1278. Encode ((byte) (0x80 | (value >> 8)));
  1279. Encode ((byte) value);
  1280. return;
  1281. }
  1282. Encode (value);
  1283. }
  1284. public byte[] ToArray ()
  1285. {
  1286. byte[] buf = new byte[pos];
  1287. Array.Copy (buffer, buf, pos);
  1288. return buf;
  1289. }
  1290. }
  1291. /// <summary>
  1292. /// Helper class for attribute verification routine.
  1293. /// </summary>
  1294. static class AttributeTester
  1295. {
  1296. /// <summary>
  1297. /// Common method for Obsolete error/warning reporting.
  1298. /// </summary>
  1299. public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report)
  1300. {
  1301. if (oa.IsError) {
  1302. Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
  1303. return;
  1304. }
  1305. if (oa.Message == null || oa.Message.Length == 0) {
  1306. Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
  1307. return;
  1308. }
  1309. Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
  1310. }
  1311. }
  1312. //
  1313. // Predefined attribute types
  1314. //
  1315. public class PredefinedAttributes
  1316. {
  1317. // Build-in attributes
  1318. public readonly PredefinedAttribute ParamArray;
  1319. public readonly PredefinedAttribute Out;
  1320. // Optional attributes
  1321. public readonly PredefinedAttribute Obsolete;
  1322. public readonly PredefinedAttribute DllImport;
  1323. public readonly PredefinedAttribute MethodImpl;
  1324. public readonly PredefinedAttribute MarshalAs;
  1325. public readonly PredefinedAttribute In;
  1326. public readonly PredefinedAttribute IndexerName;
  1327. public readonly PredefinedAttribute Conditional;
  1328. public readonly PredefinedAttribute CLSCompliant;
  1329. public readonly PredefinedAttribute Security;
  1330. public readonly PredefinedAttribute Required;
  1331. public readonly PredefinedAttribute Guid;
  1332. public readonly PredefinedAttribute AssemblyCulture;
  1333. public readonly PredefinedAttribute AssemblyVersion;
  1334. public readonly PredefinedAttribute AssemblyAlgorithmId;
  1335. public readonly PredefinedAttribute AssemblyFlags;
  1336. public readonly PredefinedAttribute AssemblyFileVersion;
  1337. public readonly PredefinedAttribute ComImport;
  1338. public readonly PredefinedAttribute CoClass;
  1339. public readonly PredefinedAttribute AttributeUsage;
  1340. public readonly PredefinedAttribute DefaultParameterValue;
  1341. public readonly PredefinedAttribute OptionalParameter;
  1342. public readonly PredefinedAttribute UnverifiableCode;
  1343. public readonly PredefinedAttribute DefaultCharset;
  1344. public readonly PredefinedAttribute TypeForwarder;
  1345. public readonly PredefinedAttribute FixedBuffer;
  1346. public readonly PredefinedAttribute CompilerGenerated;
  1347. public readonly PredefinedAttribute InternalsVisibleTo;
  1348. public readonly PredefinedAttribute RuntimeCompatibility;
  1349. public readonly PredefinedAttribute DebuggerHidden;
  1350. public readonly PredefinedAttribute UnsafeValueType;
  1351. public readonly PredefinedAttribute UnmanagedFunctionPointer;
  1352. public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable;
  1353. // New in .NET 3.5
  1354. public readonly PredefinedAttribute Extension;
  1355. // New in .NET 4.0
  1356. public readonly PredefinedDynamicAttribute Dynamic;
  1357. // New in .NET 4.5
  1358. public readonly PredefinedStateMachineAttribute AsyncStateMachine;
  1359. //
  1360. // Optional types which are used as types and for member lookup
  1361. //
  1362. public readonly PredefinedAttribute DefaultMember;
  1363. public readonly PredefinedDecimalAttribute DecimalConstant;
  1364. public readonly PredefinedAttribute StructLayout;
  1365. public readonly PredefinedAttribute FieldOffset;
  1366. public readonly PredefinedAttribute CallerMemberNameAttribute;
  1367. public readonly PredefinedAttribute CallerLineNumberAttribute;
  1368. public readonly PredefinedAttribute CallerFilePathAttribute;
  1369. public PredefinedAttributes (ModuleContainer module)
  1370. {
  1371. ParamArray = new PredefinedAttribute (module, "System", "ParamArrayAttribute");
  1372. Out = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OutAttribute");
  1373. ParamArray.Resolve ();
  1374. Out.Resolve ();
  1375. Obsolete = new PredefinedAttribute (module, "System", "ObsoleteAttribute");
  1376. DllImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DllImportAttribute");
  1377. MethodImpl = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "MethodImplAttribute");
  1378. MarshalAs = new PredefinedAttribute (module, "System.Runtime.InteropServices", "MarshalAsAttribute");
  1379. In = new PredefinedAttribute (module, "System.Runtime.InteropServices", "InAttribute");
  1380. IndexerName = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IndexerNameAttribute");
  1381. Conditional = new PredefinedAttribute (module, "System.Diagnostics", "ConditionalAttribute");
  1382. CLSCompliant = new PredefinedAttribute (module, "System", "CLSCompliantAttribute");
  1383. Security = new PredefinedAttribute (module, "System.Security.Permissions", "SecurityAttribute");
  1384. Required = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RequiredAttributeAttribute");
  1385. Guid = new PredefinedAttribute (module, "System.Runtime.InteropServices", "GuidAttribute");
  1386. AssemblyCulture = new PredefinedAttribute (module, "System.Reflection", "AssemblyCultureAttribute");
  1387. AssemblyVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyVersionAttribute");
  1388. AssemblyAlgorithmId = new PredefinedAttribute (module, "System.Reflection", "AssemblyAlgorithmIdAttribute");
  1389. AssemblyFlags = new PredefinedAttribute (module, "System.Reflection", "AssemblyFlagsAttribute");
  1390. AssemblyFileVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyFileVersionAttribute");
  1391. ComImport = new PredefinedAttribute (module, "System.Runtime.InteropServices", "ComImportAttribute");
  1392. CoClass = new PredefinedAttribute (module, "System.Runtime.InteropServices", "CoClassAttribute");
  1393. AttributeUsage = new PredefinedAttribute (module, "System", "AttributeUsageAttribute");
  1394. DefaultParameterValue = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultParameterValueAttribute");
  1395. OptionalParameter = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OptionalAttribute");
  1396. UnverifiableCode = new PredefinedAttribute (module, "System.Security", "UnverifiableCodeAttribute");
  1397. DefaultCharset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultCharSetAttribute");
  1398. TypeForwarder = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "TypeForwardedToAttribute");
  1399. FixedBuffer = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "FixedBufferAttribute");
  1400. CompilerGenerated = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
  1401. InternalsVisibleTo = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
  1402. RuntimeCompatibility = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
  1403. DebuggerHidden = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerHiddenAttribute");
  1404. UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
  1405. UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
  1406. DebuggerBrowsable = new PredefinedDebuggerBrowsableAttribute (module, "System.Diagnostics", "DebuggerBrowsableAttribute");
  1407. Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute");
  1408. Dynamic = new PredefinedDynamicAttribute (module, "System.Runtime.CompilerServices", "DynamicAttribute");
  1409. DefaultMember = new PredefinedAttribute (module, "System.Reflection", "DefaultMemberAttribute");
  1410. DecimalConstant = new PredefinedDecimalAttribute (module, "System.Runtime.CompilerServices", "DecimalConstantAttribute");
  1411. StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
  1412. FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
  1413. AsyncStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute");
  1414. CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
  1415. CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
  1416. CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
  1417. // TODO: Should define only attributes which are used for comparison
  1418. const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
  1419. System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
  1420. foreach (var fi in GetType ().GetFields (all_fields)) {
  1421. ((PredefinedAttri

Large files files are truncated, but you can click here to view the full file