Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Unified Diff: sdk/lib/mirrors/mirrors.dart

Issue 1383403002: Formatting comments for mirrors (MirrorSystem, IsolateMirror, DeclarationMirror, and ObjectMirror) (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/mirrors/mirrors.dart
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 3480cdeb608a5ed821ca5570feb275f4f3a42a25..4c23bc73622801caa500661f7b3fefc8ff92195f 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -70,12 +70,12 @@ import 'dart:async' show Future;
* or inspecting the contents of a variable) would fail dynamically.
*/
abstract class MirrorSystem {
- /**
- * Returns an immutable map from URIs to mirrors for all libraries known
- * to this mirror system. For a runtime mirror system, only libraries which
- * are currently loaded are included, and repeated calls of this method may
- * return different maps as libraries are loaded.
- */
+ /// Returns an immutable map from URIs to mirrors for all libraries known
Lasse Reichstein Nielsen 2015/10/07 08:32:25 Why change this doc-comment's format, but not the
srawlins 2015/10/07 10:26:29 Sorry, in some other libraries I've been changing
+ /// to this mirror system.
Lasse Reichstein Nielsen 2015/10/07 09:09:03 This is better described as a property: /// All l
srawlins 2015/10/07 10:26:30 Done.
+ ///
+ /// For a runtime mirror system, only libraries which are currently loaded
+ /// are included, and repeated calls of this method may return different maps
+ /// as libraries are loaded.
Map<Uri, LibraryMirror> get libraries;
/**
@@ -88,10 +88,9 @@ abstract class MirrorSystem {
(library) => library.simpleName == libraryName);
}
- /**
- * A mirror on the isolate associated with this [MirrorSystem].
- * This may be null if this mirror system is not running.
- */
+ /// A mirror on the isolate associated with this [MirrorSystem].
+ ///
+ /// This may be null if this mirror system is not running.
IsolateMirror get isolate;
/**
@@ -114,17 +113,16 @@ abstract class MirrorSystem {
*/
external static String getName(Symbol symbol);
- /**
- * Returns a symbol for [name]. If [library] is not a [LibraryMirror] or if
- * [name] is a private identifier and [library] is [:null:], throws an
- * [ArgumentError]. If [name] is a private identifier, the symbol returned is
- * with respect to [library].
- *
- * The following text is non-normative:
- *
- * Using this method may result in larger output. If possible, use
- * the const constructor of Symbol or symbol literals.
- */
+ /// Returns a symbol for [name].
+ ///
+ /// If [library] is not a [LibraryMirror] or if [name] is a private identifier
+ /// and [library] is [:null:], throws an [ArgumentError]. If [name] is a
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Cosider changing [:...:] to `...`.
srawlins 2015/10/07 10:26:29 Done.
+ /// private identifier, the symbol returned is with respect to [library].
+ ///
+ /// The following text is non-normative:
+ ///
+ /// Using this method may result in larger output. If possible, use
+ /// the const constructor of Symbol or symbol literals.
Lasse Reichstein Nielsen 2015/10/07 09:09:02 maybe: Symbol -> [Symbol]
srawlins 2015/10/07 10:26:30 Done.
external static Symbol getSymbol(String name, [LibraryMirror library]);
}
@@ -133,46 +131,39 @@ abstract class MirrorSystem {
*/
external MirrorSystem currentMirrorSystem();
-/**
- * Reflects an instance.
- * Returns an [InstanceMirror] reflecting [reflectee].
- * If [reflectee] is a function or an instance of a class
- * that has a [:call:] method, the returned instance mirror
- * will be a [ClosureMirror].
- *
- * Note that since one cannot obtain an object from
- * another isolate, this function can only be used to
- * obtain mirrors on objects of the current isolate.
- */
+/// Reflects an instance.
+///
+/// Returns an [InstanceMirror] reflecting [reflectee]. If [reflectee] is a
+/// function or an instance of a class that has a [:call:] method, the returned
+/// instance mirror will be a [ClosureMirror].
+///
+/// Note that since one cannot obtain an object from another isolate, this
+/// function can only be used to obtain mirrors on objects of the current
+/// isolate.
external InstanceMirror reflect(Object reflectee);
-/**
- * Reflects a class declaration.
- * Let *C* be the original class declaration of the class
- * represented by [key].
- * This function returns a [ClassMirror] reflecting *C*.
- *
- * If [key] is not an instance of [Type] then this function
- * throws an [ArgumentError]. If [key] is the Type for dynamic
- * or a function typedef, throws an [ArgumentError].
- *
- * Note that since one cannot obtain a [Type] object from
- * another isolate, this function can only be used to
- * obtain class mirrors on classes of the current isolate.
- */
+/// Reflects a class declaration.
+///
+/// Let *C* be the original class declaration of the class represented by [key].
+/// This function returns a [ClassMirror] reflecting *C*.
+///
+/// If [key] is not an instance of [Type] then this function throws an
+/// [ArgumentError]. If [key] is the Type for dynamic or a function typedef,
+/// throws an [ArgumentError].
+///
+/// Note that since one cannot obtain a [Type] object from another isolate, this
+/// function can only be used to obtain class mirrors on classes of the current
+/// isolate.
external ClassMirror reflectClass(Type key);
-/**
- * This function returns a [TypeMirror] reflecting the type
- * represented by [key].
- *
- * If [key] is not an instance of [Type] then this function
- * throws an [ArgumentError].
- *
- * Note that since one cannot obtain a [Type] object from
- * another isolate, this function can only be used to
- * obtain type mirrors on types of the current isolate.
- */
+/// Returns a [TypeMirror] reflecting the type represented by [key].
Lasse Reichstein Nielsen 2015/10/07 09:09:03 Inconsistent wording with the methods above. Maybe
srawlins 2015/10/07 10:26:30 Done.
+///
+/// If [key] is not an instance of [Type] then this function throws an
+/// [ArgumentError].
+///
+/// Note that since one cannot obtain a [Type] object from another isolate, this
+/// function can only be used to obtain type mirrors on types of the current
+/// isolate.
external TypeMirror reflectType(Type key);
/**
@@ -186,34 +177,23 @@ abstract class Mirror {}
* An [IsolateMirror] reflects an isolate.
*/
abstract class IsolateMirror implements Mirror {
- /**
- * Returns a unique name used to refer to an isolate
- * in debugging messages.
- */
+ /// Returns a unique name used to refer to an isolate in debugging messages.
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Describe a getter as a property: /// A unique name
srawlins 2015/10/07 10:26:29 Done.
String get debugName;
- /**
- * Returns [:true:] if and only if this mirror reflects
- * the currently running isolate. Otherwise returns
- * [:false:].
- */
+ /// Returns [:true:] if and only if this mirror reflects the currently running
+ /// isolate. Otherwise returns [:false:].
Lasse Reichstein Nielsen 2015/10/07 09:09:02 /// Whether this mirror reflects the currently run
srawlins 2015/10/07 10:26:30 Done.
bool get isCurrent;
- /**
- * Returns a [LibraryMirror] on the root library for this
- * isolate.
- */
+ /// Returns a [LibraryMirror] on the root library for this isolate.
Lasse Reichstein Nielsen 2015/10/07 09:09:02 /// The root library for the reflected isolate. //
srawlins 2015/10/07 10:26:29 I'm probably not qualified to spell out the defini
LibraryMirror get rootLibrary;
- /**
- * Returns [:true:] if this mirror is equal to [other].
- * Otherwise returns [:false:].
- * The equality holds if and only if
- * (1) [other] is a mirror of the same kind
- * and
- * (2) the isolate being reflected by this mirror is the same
- * isolate being reflected by [other].
- */
+ /// Returns [:true:] if this mirror is equal to [other].
+ ///
+ /// Otherwise returns [:false:]. The equality holds if and only if
Lasse Reichstein Nielsen 2015/10/07 09:09:03 /// Whether [other] is an [IsolateMirror] on the s
srawlins 2015/10/07 10:26:29 Done.
+ ///
+ /// 1. [other] is a mirror of the same kind, and
+ /// 2. the isolate being reflected by this mirror is the same isolate being
+ /// reflected by [other].
bool operator == (other);
}
@@ -221,13 +201,11 @@ abstract class IsolateMirror implements Mirror {
* A [DeclarationMirror] reflects some entity declared in a Dart program.
*/
abstract class DeclarationMirror implements Mirror {
- /**
- * The simple name for this Dart language entity.
- *
- * The simple name is in most cases the the identifier name of the
- * entity, such as 'method' for a method [:void method() {...}:] or
- * 'mylibrary' for a [:library 'mylibrary';:] declaration.
- */
+ /// The simple name for this Dart language entity.
+ ///
+ /// The simple name is in most cases the the identifier name of the entity,
+ /// such as 'method' for a method, [:void method() {...}:] or 'mylibrary' for
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Confusing to use "method". Maybe change to "method
srawlins 2015/10/07 10:26:29 Done.
+ /// a [:library 'mylibrary';:] declaration.
Symbol get simpleName;
/**
@@ -252,74 +230,67 @@ abstract class DeclarationMirror implements Mirror {
*/
Symbol get qualifiedName;
- /**
- * A mirror on the owner of this Dart language entity. This is the declaration
- * immediately surrounding the reflectee.
- *
- * For a library, the owner is [:null:].
- * For a class declaration, typedef or top level function
- * or variable, the owner is the enclosing library.
- * For a mixin application *S with M*, the owner is the owner
- * of *M*.
- * For a constructor, the owner is the immediately enclosing class.
- * For a method, instance variable or
- * a static variable, the owner is the immediately enclosing class,
- * unless the class is a mixin application *S with M*, in which case
- * the owner is *M*. Note that *M* may be an invocation of a generic.
- * For a parameter, local variable or local function the owner is the
- * immediately enclosing function.
- */
+ /// A mirror on the owner of this Dart language entity. This is the
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Newlines before "This". And change "This" to "The
srawlins 2015/10/07 10:26:30 Done.
+ /// declaration immediately surrounding the reflectee.
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Consider changing the final '.' to ':'.
srawlins 2015/10/07 10:26:29 Done.
+ ///
+ /// * For a library, the owner is [:null:].
Lasse Reichstein Nielsen 2015/10/07 09:09:02 These should probably be list items, so add "* " i
srawlins 2015/10/07 10:26:29 Done.
+ /// * For a class declaration, typedef or top level function or variable, the
+ /// owner is the enclosing library.
+ /// * For a mixin application *S with M*, the owner is the owner of *M*.
Lasse Reichstein Nielsen 2015/10/07 09:09:03 *S with M* -> `S with M` dittos below
srawlins 2015/10/07 10:26:30 Done.
+ /// * For a constructor, the owner is the immediately enclosing class.
+ /// * For a method, instance variable or a static variable, the owner is the
+ /// immediately enclosing class, unless the class is a mixin application
+ /// *S with M*, in which case the owner is *M*. Note that *M* may be an
+ /// invocation of a generic.
+ /// * For a parameter, local variable or local function the owner is the
+ /// immediately enclosing function.
DeclarationMirror get owner;
- /**
- * Returns [:true:] if this declaration is considered private
- * according to the Dart language specification.
- * Always returns [: false :] if this declaration
- * is a library.
- * Otherwise return [:false:].
- *
- */
+ /// Returns [:true:] if this declaration is considered private according to
Lasse Reichstein Nielsen 2015/10/07 09:09:03 /// Whether this declaration is library private. /
srawlins 2015/10/07 10:26:29 Done.
+ /// the Dart language specification.
+ ///
+ /// Always returns [: false :] if this declaration is a library. Otherwise
+ /// return [:false:].
bool get isPrivate;
- /**
- * Is this declaration top-level?
- *
- * This is defined to be equivalent to:
- * [:mirror.owner != null && mirror.owner is LibraryMirror:]
- */
+ /// Is this declaration top-level?
Lasse Reichstein Nielsen 2015/10/07 09:09:02 /// Whether this declaration is top-level. /// ///
srawlins 2015/10/07 10:26:29 Done.
+ ///
+ /// This is defined to be equivalent to:
+ /// [:mirror.owner != null && mirror.owner is LibraryMirror:].
bool get isTopLevel;
- /**
- * The source location of this Dart language entity, or [:null:] if the
- * entity is synthetic.
- *
- * If the reflectee is a variable, the returned location gives the position of * the variable name at its point of declaration.
- *
- * If the reflectee is a library, class, typedef, function or type variable
- * with associated metadata, the returned location gives the position of the
- * first metadata declaration associated with the reflectee.
- *
- * Otherwise:
- * If the reflectee is a library, the returned location gives the position of
- * the keyword 'library' at the reflectee's point of declaration, if the
- * reflectee is a named library, or the first character of the first line in
- * the compilation unit defining the reflectee if the reflectee is anonymous.
- *
- * If the reflectee is an abstract class, the returned location gives the
- * position of the keyword 'abstract' at the reflectee's point of declaration. * Otherwise, if the reflectee is a class, the returned location gives the
- * position of the keyword 'class' at the reflectee's point of declaration.
- *
- * If the reflectee is a typedef the returned location gives the position of
- * the of the keyword 'typedef' at the reflectee's point of declaration.
- *
- * If the reflectee is a function with a declared return type, the returned
- * location gives the position of the function's return type at the
- * reflectee's point of declaration. Otherwise. the returned location gives
- * the position of the function's name at the reflectee's point of
- * declaration.
- *
- * This operation is optional and may throw an [UnsupportedError].
- */
+ /// The source location of this Dart language entity, or [:null:] if the
+ /// entity is synthetic.
+ ///
+ /// If the reflectee is a variable, the returned location gives the position
+ /// of the variable name at its point of declaration.
+ ///
+ /// If the reflectee is a library, class, typedef, function or type variable
+ /// with associated metadata, the returned location gives the position of the
+ /// first metadata declaration associated with the reflectee.
+ ///
+ /// Otherwise:
+ ///
+ /// If the reflectee is a library, the returned location gives the position of
+ /// the keyword 'library' at the reflectee's point of declaration, if the
+ /// reflectee is a named library, or the first character of the first line in
+ /// the compilation unit defining the reflectee if the reflectee is anonymous.
+ ///
+ /// If the reflectee is an abstract class, the returned location gives the
+ /// position of the keyword 'abstract' at the reflectee's point of declaration.
+ /// Otherwise, if the reflectee is a class, the returned location gives the
+ /// position of the keyword 'class' at the reflectee's point of declaration.
+ ///
+ /// If the reflectee is a typedef the returned location gives the position of
+ /// the of the keyword 'typedef' at the reflectee's point of declaration.
+ ///
+ /// If the reflectee is a function with a declared return type, the returned
+ /// location gives the position of the function's return type at the
+ /// reflectee's point of declaration. Otherwise. the returned location gives
+ /// the position of the function's name at the reflectee's point of
+ /// declaration.
Lasse Reichstein Nielsen 2015/10/07 09:09:02 Interesting ... it does not include "static" or "e
srawlins 2015/10/07 10:26:29 Acknowledged.
+ ///
+ /// This operation is optional and may throw an [UnsupportedError].
SourceLocation get location;
/**
@@ -356,28 +327,25 @@ abstract class DeclarationMirror implements Mirror {
*/
abstract class ObjectMirror implements Mirror {
- /**
- * Invokes the named function and returns a mirror on the result.
- *
- * Let *o* be the object reflected by this mirror, let
- * *f* be the simple name of the member denoted by [memberName],
- * let *a1, ..., an* be the elements of [positionalArguments]
- * let *k1, ..., km* be the identifiers denoted by the elements of
- * [namedArguments.keys]
- * and let *v1, ..., vm* be the elements of [namedArguments.values].
- * Then this method will perform the method invocation
- * *o.f(a1, ..., an, k1: v1, ..., km: vm)*
- * in a scope that has access to the private members
- * of *o* (if *o* is a class or library) or the private members of the
- * class of *o* (otherwise).
- * If the invocation returns a result *r*, this method returns
- * the result of calling [reflect]\(*r*\).
- * If the invocation causes a compilation error
- * the effect is the same as if a non-reflective compilation error
- * had been encountered.
- * If the invocation throws an exception *e* (that it does not catch)
- * this method throws *e*.
- */
+ /// Invokes the named function and returns a mirror on the result.
+ ///
+ /// Let *o* be the object reflected by this mirror, let *f* be the simple name
+ /// of the member denoted by [memberName], let *a1, ..., an* be the elements
+ /// of [positionalArguments], let *k1, ..., km* be the identifiers denoted by
+ /// the elements of [namedArguments.keys], and let *v1, ..., vm* be the
+ /// elements of [namedArguments.values]. Then this method will perform the
+ /// method invocation *o.f(a1, ..., an, k1: v1, ..., km: vm)* in a scope that
+ /// has access to the private members of *o* (if *o* is a class or library) or
+ /// the private members of the class of *o* (otherwise).
Lasse Reichstein Nielsen 2015/10/07 09:09:03 Reflow reduces the readability/editability of the
srawlins 2015/10/07 10:26:29 This means it is equally not readable online: htt
Lasse Reichstein Nielsen 2015/10/07 18:05:56 I think bulleted would be better, maybe reworded a
Lasse Reichstein Nielsen 2015/10/07 18:06:39 I prefer to make it readable in one case rather th
+ ///
+ /// If the invocation returns a result *r*, this method returns the result of
+ /// calling [reflect]\(*r*\).
+ ///
+ /// If the invocation causes a compilation error the effect is the same as if
+ /// a non-reflective compilation error had been encountered.
+ ///
+ /// If the invocation throws an exception *e* (that it does not catch), this
+ /// method throws *e*.
/*
* TODO(turnidge): Handle ambiguous names.
* TODO(turnidge): Handle optional & named arguments.
@@ -386,82 +354,77 @@ abstract class ObjectMirror implements Mirror {
List positionalArguments,
[Map<Symbol,dynamic> namedArguments]);
- /**
- * Invokes a getter and returns a mirror on the result. The getter
- * can be the implicit getter for a field or a user-defined getter
- * method.
- *
- * Let *o* be the object reflected by this mirror, let
- * *f* be the simple name of the getter denoted by [fieldName],
- * Then this method will perform the getter invocation
- * *o.f*
- * in a scope that has access to the private members
- * of *o* (if *o* is a class or library) or the private members of the
- * class of *o* (otherwise).
- *
- * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance
- * method on its reflectee, the result of the invocation is an instance
- * mirror on a closure corresponding to that method.
- *
- * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
- * method in the corresponding library, the result of the invocation is an
- * instance mirror on a closure corresponding to that method.
- *
- * If this mirror is a [ClassMirror], and [fieldName] denotes a static method
- * in the corresponding class, the result of the invocation is an instance
- * mirror on a closure corresponding to that method.
- *
- * If the invocation returns a result *r*, this method returns
- * the result of calling [reflect]\(*r*\).
- * If the invocation causes a compilation error
- * the effect is the same as if a non-reflective compilation error
- * had been encountered.
- * If the invocation throws an exception *e* (that it does not catch)
- * this method throws *e*.
- */
+ /// Invokes a getter and returns a mirror on the result.
+ ///
+ /// The getter can be the implicit getter for a field or a user-defined getter
+ /// method.
+ ///
+ /// Let *o* be the object reflected by this mirror, let *f* be the simple name
Lasse Reichstein Nielsen 2015/10/07 09:09:03 *f* -> `f` More below.
srawlins 2015/10/07 10:26:29 This *f* format is everywhere in this file. Maybe
+ /// of the getter denoted by [fieldName]. Then this method will perform the
+ /// getter invocation *o.f* in a scope that has access to the private members
+ /// of *o* (if *o* is a class or library) or the private members of the class
+ /// of *o* (otherwise).
+ ///
+ /// If this mirror is an [InstanceMirror], and [fieldName] denotes an instance
+ /// method on its reflectee, the result of the invocation is an instance
+ /// mirror on a closure corresponding to that method.
+ ///
+ /// If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
+ /// method in the corresponding library, the result of the invocation is an
+ /// instance mirror on a closure corresponding to that method.
+ ///
+ /// If this mirror is a [ClassMirror], and [fieldName] denotes a static method
+ /// in the corresponding class, the result of the invocation is an instance
+ /// mirror on a closure corresponding to that method.
+ ///
+ /// If the invocation returns a result *r*, this method returns the result of
+ /// calling [reflect]\(*r*\).
+ ///
+ /// If the invocation causes a compilation error, the effect is the same as if
+ /// a non-reflective compilation error had been encountered.
+ ///
+ /// If the invocation throws an exception *e* (that it does not catch), this
+ /// method throws *e*.
// TODO(ahe): Remove stuff about scope and private members. [fieldName] is a
// capability giving access to private members.
InstanceMirror getField(Symbol fieldName);
- /**
- * Invokes a setter and returns a mirror on the result. The setter
- * may be either the implicit setter for a non-final field or a
- * user-defined setter method.
- *
- * Let *o* be the object reflected by this mirror, let
- * *f* be the simple name of the getter denoted by [fieldName],
- * and let *a* be the object bound to [value].
- * Then this method will perform the setter invocation
- * *o.f = a*
- * in a scope that has access to the private members
- * of *o* (if *o* is a class or library) or the private members of the
- * class of *o* (otherwise).
- * If the invocation returns a result *r*, this method returns
- * the result of calling [reflect]\([value]\).
- * If the invocation causes a compilation error
- * the effect is the same as if a non-reflective compilation error
- * had been encountered.
- * If the invocation throws an exception *e* (that it does not catch)
- * this method throws *e*.
- */
+ /// Invokes a setter and returns a mirror on the result.
+ ///
+ /// The setter may be either the implicit setter for a non-final field or a
+ /// user-defined setter method.
+ ///
+ /// Let *o* be the object reflected by this mirror, let *f* be the simple name
+ /// of the getter denoted by [fieldName], and let *a* be the object bound to
+ /// [value]. Then this method will perform the setter invocation *o.f = a* in
+ /// a scope that has access to the private members of *o* (if *o* is a class
+ /// or library) or the private members of the class of *o* (otherwise).
+ ///
+ /// If the invocation returns a result *r*, this method returns the result of
+ /// calling [reflect]\([value]\).
+ ///
+ /// If the invocation causes a compilation error, the effect is the same as if
+ /// a non-reflective compilation error had been encountered.
+ ///
+ /// If the invocation throws an exception *e* (that it does not catch) this
+ /// method throws *e*.
/* TODO(turnidge): Handle ambiguous names.*/
InstanceMirror setField(Symbol fieldName, Object value);
- /**
- * Perform [invocation] on [reflectee].
- * Equivalent to
- *
- * if (invocation.isGetter) {
- * return this.getField(invocation.memberName).reflectee;
- * } else if (invocation.isSetter) {
- * return this.setField(invocation.memberName,
- * invocation.positionArguments[0]).reflectee;
- * } else {
- * return this.invoke(invocation.memberName,
- * invocation.positionalArguments,
- * invocation.namedArguments).reflectee;
- * }
- */
+ /// Perform [invocation] on [reflectee].
+ ///
+ /// Equivalent to
+ ///
+ /// if (invocation.isGetter) {
+ /// return this.getField(invocation.memberName).reflectee;
+ /// } else if (invocation.isSetter) {
+ /// return this.setField(invocation.memberName,
+ /// invocation.positionArguments[0]).reflectee;
+ /// } else {
+ /// return this.invoke(invocation.memberName,
+ /// invocation.positionalArguments,
+ /// invocation.namedArguments).reflectee;
+ /// }
delegate(Invocation invocation);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698