Annotating Methods in Delphi? - delphi

I have a piece of code that needs some serious documenting and wanted to ask whether a feature similar to C#/.NET's In-code XML-Documentation is available for Embarcadero Delphi.
My aim is to display some sort of information on how to use a specific method correctly in the manner that it'd be highlighted in the Autocompletion in Delphi XE3.
Something like this (C#):
/// <summary>
/// Some useful information helping other developers use this method correctly
/// </summary>
public static void ADocumentedMethod();
Does Delphi XE3 support something like this?
Thank you for reading.

The feature is named XML Documentation Comments and is documented here. It appears to have been modelled closely on the equivalent .net feature so you should be right at home with it.
The documentation contains this example:
/// <summary> Removes the specified item from the collection
/// </summary>
/// <param name="Item">The item to remove
/// </param>
/// <param name="Collection">The group containing the item
/// </param>
/// <remarks>
/// If parameter "Item" is null, an exception is raised.
/// <see cref="EArgumentNilException"/>
/// </remarks>
/// <returns>True if the specified item is successfully removed;
/// otherwise False is returned.
/// </returns>
function RemoveItem(Item: Pointer; Collection: Pointer): Boolean;
begin
// Non-XML DOC comment
// ...
end;
which results in this help insight hint:
And there are various other ways to process and consume the documentation.

Related

How to see dart core library code (StringBuffer)?

I just wondered how the StringBuffer's concrete code is look like.
But I can only find abstract method like this. Well...
Could you please let me know how to get to the concrete code ? Thanks!
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.core;
class StringBuffer implements StringSink {
/// Creates a string buffer containing the provided [content].
external StringBuffer([Object content = ""]);
/// Returns the length of the content that has been accumulated so far.
/// This is a constant-time operation.
external int get length;
/// Returns whether the buffer is empty. This is a constant-time operation.
bool get isEmpty => length == 0;
/// Returns whether the buffer is not empty. This is a constant-time
/// operation.
bool get isNotEmpty => !isEmpty;
/// Adds the string representation of [object] to the buffer.
external void write(Object? object);
/// Adds the string representation of [charCode] to the buffer.
///
/// Equivalent to `write(String.fromCharCode(charCode))`.
external void writeCharCode(int charCode);
/// Writes all [objects] separated by [separator].
///
/// Writes each individual object in [objects] in iteration order,
/// and writes [separator] between any two objects.
external void writeAll(Iterable<dynamic> objects, [String separator = ""]);
external void writeln([Object? obj = ""]);
/// Clears the string buffer.
external void clear();
/// Returns the contents of buffer as a single string.
external String toString();
}
It depends on what target platform you are interested in which is also the reason why the do this since the external function can point to different implementation depending on target.
The implementation for the different platforms can be found here:
https://github.com/dart-lang/sdk/tree/2.18.1/sdk/lib/_internal
So if you want to see the implementation used when running the Dart VM or compiled to AOT binary, the implementation of StringBuffer can be found here:
https://github.com/dart-lang/sdk/blob/2.18.1/sdk/lib/_internal/vm/lib/string_buffer_patch.dart
Another point here is that Dart VM code often have stuff like the following which you can see in the bottom of the StringBuffer implementation:
#pragma("vm:external-name", "StringBuffer_createStringFromUint16Array")
external static String _create(Uint16List buffer, int length, bool isLatin1);
This means that we do a call to the C++ code in the Dart runtime (which is bundled together with your compiled app). So the _create call will end up calling the following method:
https://github.com/dart-lang/sdk/blob/2.18.1/runtime/lib/string.cc#L516-L534
If your target are instead JavaScript, the code used for that implementation (when compiled to a release ready JS bundle) can be found here:
https://github.com/dart-lang/sdk/blob/2.18.1/sdk/lib/_internal/js_runtime/lib/core_patch.dart#L632

How to use Global variables in Ranorex?

I need to create and use global variable as optional parameter, but do not know how I can implement it.
I created the global variable in Ranorex studio:
Also this variable appeared in Data binding tag:
But I can't use this variable in the code. (ASECore package do not contains any parameters).
You can use the global Variables in Ranorex Record module or Ranorex Code module. Let me please first make an introduction of how to use them.
Create in Record module
In the Record module, click button Variables... in the top right corner and add the variables you want to use in the redord module.
Then use them in your recording:
Create in Code module
When you create a code module, it will look like this:
/// <summary>
/// Description of MyCode.
/// </summary>
[TestModule("32310FEC-5336-4F83-B448-ABC851EE5731", ModuleType.UserCode, 1)]
public class MyCode : ITestModule
{
/// <summary>
/// Constructs a new instance.
/// </summary>
public MyCode()
{
// Do not delete - a parameterless constructor is required!
}
/// <summary>
/// Performs the playback of actions in this module.
/// </summary>
/// <remarks>You should not call this method directly, instead pass the module
/// instance to the <see cref="TestModuleRunner.Run(ITestModule)"/> method
/// that will in turn invoke this method.</remarks>
void ITestModule.Run()
{
Mouse.DefaultMoveTime = 300;
Keyboard.DefaultKeyPressTime = 100;
Delay.SpeedFactor = 1.0;
}
}
Now, right click in the code and choose "Insert new module variable". Then you can set a name and default value. Press ok and it will add something like this:
string _MyVariable = "DefaultValue";
[TestVariable("de0fb4a9-32ba-4635-8f0f-4ff6db184c3f")]
public string MyVariable
{
get { return _MyVariable; }
set { _MyVariable = value; }
}
Now, you can use the variables in the run method like normal C# properties:
repo.Calculator.CalculatorResults.PressKeys(Input_1);
repo.Calculator.PlusButton.Click();
repo.Calculator.CalculatorResults.PressKeys(Input_2);
repo.Calculator.EqualButton.Click();
How to bind Variables in Suite
When you created the global parameters, it's true that you can not bind them on the suite level.
Therefore close the dialog and right click on the Record/Code module and choose "Data binding"
In the lower table you can bind your variables of the Record/Code module to the global variables. If they have the same name, you can also Auto-bind them.
When you now execute the test suite, the values of the global variables will be used in test. If you execute the Record/Code module standalone, then the default values will be used in test.
Once you have set that variable in your highest node, you can use it and assign variables to it in lower nodes. So when you make a smart folder in your test suite and go to the data binding, you will notice the global is present under the parameters. All you need to do is make a recording with a variable that will use the global variable and link it in that folder.

Serilog Sink ddls are not copied when reference only in appsettings

I am using serilog with the sinks File and RollingFile in a crosscutting dll that delivers a logging service. I am configuring with the Appsettings nuget, therefore I have no static dependency to the mentioned sinks. However I do need them at runtime and they are not copied to the bin folder of the application, only to the bin folder of the dll. That means I get a Runtime Exception because the sink-dlls are not there. Is there a way to fix that? My workaround is creating a Variable of type RollingFileSink that I never use. But it is kind of ugly. UPDATE: that solution does not work in Release btw.
I had this issue before with Serilog, and the way I resolved it was to create a static reference to a type inside the assemblies I needed, via an assembly-level attribute that I declare inside the AssemblyInfo.cs of my main project.
Something like this:
[assembly: ImplicitDependency(typeof(Serilog.Sinks.RollingFile.RollingFileSink))]
[assembly: ImplicitDependency(typeof(Serilog.Sinks.File.PeriodicFlushToDiskSink))]
// etc...
And this is the attribute I created inside my project...
/// <summary>
/// Indicates that the marked assembly depends on the type that is specified in the constructor.
/// Typically used to force a compile-time dependency to the assembly that contains the type.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ImplicitDependencyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ImplicitDependencyAttribute"/> class.
/// </summary>
/// <param name="dependencyType">A type from the assembly that is used dynamically.</param>
public ImplicitDependencyAttribute(Type dependencyType)
{
DependencyType = dependencyType;
}
/// <summary>
/// Gets the dependent type reference.
/// </summary>
/// <value>The dependent type reference.</value>
public Type DependencyType { get; private set; }
}

Documenting F# Code

In a C# class with a single constructor, I can add class summary XML documentation and constructor XML documentation:
///<summary>
///This class will solve all your problems
///</summary>
public class Awesome
{
/// <summary>
/// Initializes a new instance of the <see cref="Awesome"/> class.
/// </summary>
/// <param name="sauce">The secret sauce.</param>
public Awesome(string sauce)
{
//...implementation elided for security purposes
}
}
How do I do the same with the equivalent F# class such that the generated documentation is the same?
type Awesome(sauce: string) =
//...implementation elided for security purposes
CLARIFICATION: I'm aware that the standard XML documentation tags can be used in F#. My question is how to add them to the above snippet so that both the type and the constructor are documented.
I looked at the source of the open-source F# compiler and I think Dr_Asik is right - there is no way of documenting the implicit constructor with an XML comment. The node that represents the implicit constructor in the AST (See ImplicitCtor in ast.fs here) does not include a field for stroing the XML documentation (represented as PreXmlDoc type).
You can still document all public API - you'd have to use the method that Dr_Asik mentioned and mark the implicit constructor as private. I agree this is a bit ugly, but I think it is more convenient than not using implicit constructors:
type MyType private(a:int, u:unit) =
/// <summary>Creates MyType</summary>
/// <param name="a">Parameter A</param>
new(a:int) = MyType(a, ())
I added a dummy parameter u to the implicit constructor, so that it can be called from the public constructor. Anyway, I think this should be considered as a language bug and so I'd suggest reporting this to fsbugs at microsoft dot com.
As an aside, I think the XML documentation is mainly useful as a source of data for IntelliSense (which still needs documentation for the constructor, though) and I created some alternative F# tools that let you create tutorials and documentation by writing an F# script file with special comments using Markdown (there is a blog post about it) - so you may consider that as a useful addition to the standard XML tooling.
In exactly the same way as you do in C#: http://msdn.microsoft.com/en-us/library/dd233217.aspx
If you don't put any tags, F# assumes it is "summary":
/// This is the documentation
type MyType() = ....
... is equivalent to
/// <summary>This is the documentation</summary>
type MyType() = ...
If you want to document a constructor, you'll have to declare it explicitely. AFAIK there is no way to document the primary constructor.
/// [Type summary goes here]
type MyType(a : int) =
let m_a = a
/// [Parameterless constructor documentation here]
new() = MyType(0)
There is no way to document the implicit constructor with an XML comment inside an F# source file (.fs). One workaround is to declare the constructor explicitly (see Dr Asik's answer). Another is to put your XML comments into an F# Signature File (.fsi).
File.fs:
module File
type Awesome(sauce: string) =
member x.Sauce = sauce
File.fsi
module File
type Awesome =
class
/// Implicit constructor summary for the Awesome type
new : sauce:string -> Awesome
member Sauce : string
end
The XML documentation for this assembly will now contain the correct summary:
<member name="M:File.Awesome.#ctor(System.String)">
<summary>
Implicit constructor summary for the Awesome type
</summary>
</member>
This really is an annoying problem.
Another solution I ended up using is to not rely on a primary constructor:
/// Documentation type.
type Awesome =
val sauce : string
/// <summary>Documentation constructor.</summary>
/// <param name="sauce">Sauce. Lots of it.</param>
new (sauce) = { sauce = sauce }
More verbose, but no extra files or private constructors needed...

How do I register an object with the IApplicationContext in Spring.Net?

Spring documentation on http://springframework.net/docs/1.3.1/reference/html/objects.html says:
"In addition to object definitions which contain information on how to
create a specific object, the IApplicationContext implementations also
permit the registration of existing objects that are created outside
the container, by users. This is done by accessing the
ApplicationContext's IObjectFactory via the property ObjectFactory
which returns the IObjectFactory implementation
DefaultListableObjectFactory. DefaultListableObjectFactory supports
registration through the methods RegisterSingleton(..) and
RegisterObjectDefinition(..)."
I'm trying to access the ObjectFactory object after doing the following:
var context = ContextRegistry.GetContext();
But there is no ObjectFactory property. I'm using Spring.Net v1.3.1.20711 and have Spring.Core referenced in my project.
What am I missing?
The ObjectFactory property is not exposed by the IApplicationContext interface, but is part of the IConfigurableListableObjectFactory interface.
Your context variable will be of inferred type IApplicationContext, because of the return type of ContextRegistry.GetContext(), so in VS it will appear that the ObjectFactory property is not available. However, if you take a closer look, you will see that it is an XmlApplicationContext that has the ObjectFactory property, because it implements IConfigurableListableObjectFactory. As Sebastian points out in his answer, most (if not all) application contexts implement this interface.
E.g.:
var ctx = new XmlApplicationContext("objects.xml");
ctx.ObjectFactory.RegisterSingleton("MyObject2", new MyClass() { Name = "MyObject2"});
var o2 = (MyClass)ctx.GetObject("MyObject2");
Assert.AreEqual("MyObject2", o2.Name);
Just to add to Marjin's answer; here is an extension method to get the Factory which I use.
/// <summary>
/// Gets the ObjectFactory from the Spring context.
/// </summary>
/// <param name="context">The context.</param>
/// <returns></returns>
public static IConfigurableListableObjectFactory Factory(this IApplicationContext context)
{
return ((IConfigurableApplicationContext)context).ObjectFactory;
}

Resources