Difference between revisions of "Code Templates"

m (Code Templates)
m (Schema)
 
(7 intermediate revisions by the same user not shown)
Line 67: Line 67:
 
       </literal>
 
       </literal>
 
        
 
        
       <object id="list" conforms="LIST [ANY]" editable="true">
+
       <object id="list" conforms_to="LIST [ANY]" editable="true">
 
         <description>Variable that is of a Eiffel list type structure, containing a for_all call.</description>
 
         <description>Variable that is of a Eiffel list type structure, containing a for_all call.</description>
 +
        <default>entity</default>
 
       </object>
 
       </object>
 
     </declarations>
 
     </declarations>
Line 104: Line 105:
 
* ''contract'': Templates used within the scope of a contract.
 
* ''contract'': Templates used within the scope of a contract.
  
Finally, '''shortcut''' is an Eiffel-like identifier ([a-zA-Z][a-zA-Z0-9_]*) which can be used by aspects of a tool's UI, such as an editor, to render a code template using shorthand identifier, rather than use a slower system of code template navigation. Template expansion will come probably via the enter to the shortcut as text with a following key-based shortcut to expand the shortcut into a fully rendered code template. This is purely to assists end-users when typing, to retain edit-flow without having to resort to showing completion or any other UI to insert and render a code template.
+
Finally, '''shortcut''' is an Eiffel-like identifier ([a-zA-Z][a-zA-Z0-9_]*) which can be used by aspects of a tool's UI, such as an editor, to render a code template using shorthand identifier, rather than use a slower UI-based system of code template navigation. Template expansion will come probably via the enter to the shortcut as text with a following key-based shortcut to expand the shortcut into a fully rendered code template. This is purely to assists end-users when typing, to retain edit-flow without having to resort to showing completion or any other UI to insert and render a code template.
  
 
== Code Library References ==
 
== Code Library References ==
Line 145: Line 146:
  
 
=== Assembly Library References ===
 
=== Assembly Library References ===
Assembly references are specified using the fusion name parts. '''name''' will always be required, as it is when attempting to load an assembly using the Common Language Runtime. All other parts are optional and will be used to narrow multiple matches.
+
Assembly references are specific to only .NET projects and are specified using the fusion name parts. '''name''' will always be required, as it is when attempting to load an assembly using the Common Language Runtime. All other parts are optional and will be used to narrow multiple matches; '''version''' indicates the minimum version of the assembly to, '''culture''' indicates the assembly located required when referencing an assembly and finally, '''key''' indicates the assembly's public key token, required to match any located assembly.
  
'''version''' indicates the minimum version of the assembly to
+
== Code Template Declarations ==
 +
In order to facilitate code templates, variables will be required to replaces parts of the template with user supplied parameters.
  
'''culture''' indicates the assembly located required when referencing an assembly.
+
=== Literal Declarations ===
  
'''key''' indicates the assembly's public key token, required to match any located assembly.
+
Literal code definitions types are declaration variables that can be replaced in a code template text. There are two forms of literal declarations; simple, editable declarations and functional literals that retrieve their value from an in-built function.
 +
 
 +
Every literal declaration is created using a '''literal''' element with an ''id'' attribute, defined using the Eiffel identifier rules ([a-zA-Z][a-zA-Z0-9_]*]), which will be used in a tokenized code template text block. ''id'' should contain a unique indentifer to the code template file, as not to conflict with any other declaration. Each literal will contain another optional Boolean attribute ''editable'' indicating if the literal declaration can be edited by the user. The ''editable'' attribute is another piece of code template information for the UI. It should indicate to the UI if the user is able to directly edit the variable or if the value is retrieve from a default or internally.
 +
 
 +
==== Basic ====
 +
 
 +
The most fundamental literal declarations should be simple to define. As already stated, the '''literal''' element should be used and the ''id'' attribute present. The ''editable'' attribute should also be applicable and effective even in the simplest of declarations.
 +
 
 +
Ever literal needs a value, as a suggestion, place holder or indication of the value. For instance, if the code template mechanism is integrated into the editor, the rendered template should highlight  portions of the code template text to indicate declarations that can be replaced. If there is no suggested or default value then it is impossible to display any indication. Rendered programmatically there is still a need for a default value.
 +
 
 +
<code>[xml]
 +
<literal id="var" editable="true">
 +
</code>
 +
 
 +
<code>[xml]
 +
<literal id="var" editable="true">
 +
  <description>Editable literal.</description>
 +
  <default>default value</default>
 +
<literal>
 +
</code>
  
 
== Code Templates ==
 
== Code Templates ==
Line 197: Line 218:
 
</code>
 
</code>
  
 +
Because there is no minimum version specified for the template, regardless of the compiler used or targeted, the template will be rendered upon request.
  
 +
=== Platform Dependent Templates ===
  
Because there is no minimum version specified for the template, regardless of the compiler used or targeted, the template will be rendered upon request.
+
It will probably be necessary at some point to develop code templates that function for a specific platform or code generation target. For the simplification of the code template schema, platform segregation should be performed through organization of an installation. Currently this accomplished by the Eiffel compiler's built-in mechanism.
  
 
== Contract Editor Requirements ==
 
== Contract Editor Requirements ==
Line 235: Line 258:
  
 
For 6.2 code template versions will '''not''' be supported but the structuring for specifying code '''templates''' will be preserved for future proofing the contract code templates.
 
For 6.2 code template versions will '''not''' be supported but the structuring for specifying code '''templates''' will be preserved for future proofing the contract code templates.
 +
 +
===  ===
 +
To ensure correct formatting and yet clarity of a code template declaration template delimiters can be used in a template declaration.
 +
 +
<code>
 +
  <templates>
 +
    <template>
 +
~#
 +
code template
 +
#~
 +
    </template>
 +
  </templates>
 +
</code>
 +
 +
The template start (~#) and end (#~) delimiters can either be placed on their own line or placed before and after the template on the same line. In either case the trailing white-space after the start delimiter (~#) and the leading white-space before the end delimiter (#~) is removed. Without the delimiters all white-space is preserved.
 +
 +
To illustrate the semantics of the delimiters, consider the following template:
 +
 +
<code>
 +
  <templates>
 +
    <template>
 +
$var /= Void
 +
    </template>
 +
  </templates>
 +
</code>
 +
 +
In Eiffel code would be
 +
 +
<eiffel>
 +
f
 +
  do
 +
    if | then
 +
    end
 +
  end
 +
</eiffel>
 +
 +
Inserting the template would result in the following code:
 +
 +
<eiffel>
 +
f
 +
  do
 +
    if
 +
    var /= Void
 +
        then
 +
    end
 +
  end
 +
</eiffel>
 +
 +
The template has inserted extra line breaks and white space before and after the actual template. To correct the template can be rewritten as follows:
 +
 +
<code>
 +
  <templates>
 +
    <template>$var /= Void</template>
 +
  </templates>
 +
</code>
 +
 +
Or using delimiters:
 +
 +
<code>
 +
  <templates>
 +
    <template>
 +
 +
~#
 +
$var /= Void
 +
#~
 +
 +
    </template>
 +
  </templates>
 +
</code>

Latest revision as of 13:28, 9 April 2008

Construction.png Not Ready for Review: This Page is Under Development!

This page is used to refine the specification for a code template mechanism in future releases of EiffelStudio.

Initial Design Descisions

For now XML has been chosen to describe code templates because is it structured, easy to read (programmatically) and can be converted with relative ease using transformation scripts.

The information discussed here is by no means final or reflects any work current under way. It's used to formualize a schema, part of which may be in the release of 6.2 under use in the Contract Editor Tool.

Schema

<code_templates format="1.0.0">
  <code_template>
 
    <metadata>
      <title>Completion title</title>
      <description>Code template description, for completion tooltip and other UI.</description>
      <author>Eiffel Software</author>
      <shortcut>shortcut</shortcut>
      <categories>
        <category>contract</category>
        <category>code</category>
        <category>class</category>
      </categories>
    </metadata>
 
    <references>
      <reference>
        <library location="$ISE_LIBRARY/base/base.ecf"/>
      </reference>
      <reference>
        <library id="6D7FF712-BBA5-4AC0-AABF-2D9880493A01"/>
      </reference>
      <reference>
        <assembly>mscorlib.dll</assembly>
        <version>2.0.54727</version>
      </reference>
      <reference>
        <assembly>System.dll</assembly>
      </reference>
    </references>
 
    <declarations>
      <choice id="opt">
        <description>Choice declaration.</description>
        <choices>
          <item>do</item>
          <item>once</item>
          <item>deferred</item>
        </choices>
      </choice>
 
      <literal id="var" editable="true">
        <description>Editable literal.</description>
        <default>default value</default>
      </literal>
 
      <literal id="var2" editable="false">
        <description>Function evaluation, non-editable but can be editable.</description>
        <default>CLASS_NAME</default>
        <function name="builtin_function">
          <arg type="STRING_32">make</arg>
          <arg>default to string</arg>
          <arg type="INTEGER_32">-12</arg>
        </function>
      </literal>
 
      <object id="list" conforms_to="LIST [ANY]" editable="true">
        <description>Variable that is of a Eiffel list type structure, containing a for_all call.</description>
        <default>entity</default>
      </object>
    </declarations>
 
    <templates>
      <template><![CDATA[${list}_contains_attached_items: not ${list}.has (Void)${cursor}]]></template>
    </templates>
 
  </code_template>
</code_templates>

Metadata

The metadata section describes the code template. It has no functional effect on the template or how it is rendered, the information is purely informative and is used by tools consuming the code template definition. As a result the entire metadata section of the code template could be optional, as with each element. However for the purpose of UI related integration, some elements should be made mandatory.

Below shows an initial draft of the metadata section of a code template:

<metadata>
  <title>Short title</title>
  <description>Code template description.</description>
  <author>Eiffel Software</author>
  <categories>
    <category>class</category>
    <category>contract</category>
    <category>code</category>
  </categories>
  <shortcut>shortcut</shortcut>
</metadata>

The title element is used to title the code template. It is to be a terse description to be shown in parts of the EiffelStudio UI; such parts as the completion window, in a code template manager or other aspects of the UI where brevity is required. description on the other hand is more verbose and deeper explains the function of the code template, to explain all that title is unable to. author is last element used in describing the code template, for acknowledgment and possible classification.

To ensure assistance context for the UI, categories, defined by the use of the categories and category elements, classify the code template. The classification can be used to ensure only applicable code templates are display for given code contexts. There are no set categories, but by default there should be three well-known categories for contextual assistance when editing an Eiffel class using a tool such as EiffelStudio:

  • class: Templates used within the scope of a class, encompassing everything external of a feature declaration.
  • code: Templates used within the scope of a routine body only.
  • contract: Templates used within the scope of a contract.

Finally, shortcut is an Eiffel-like identifier ([a-zA-Z][a-zA-Z0-9_]*) which can be used by aspects of a tool's UI, such as an editor, to render a code template using shorthand identifier, rather than use a slower UI-based system of code template navigation. Template expansion will come probably via the enter to the shortcut as text with a following key-based shortcut to expand the shortcut into a fully rendered code template. This is purely to assists end-users when typing, to retain edit-flow without having to resort to showing completion or any other UI to insert and render a code template.

Code Library References

When using code templates, the template code may require the direct inclusion of an Eiffel library and/or .NET assembly. This section of the code template is completely option and is used by the engine to manipulate a loaded Eiffel project to ensure successful code compilation when using a code template.

A good example of the need to include library references is when authoring a code template for, say, the cURL library. A code template may be authored to process a URL and fill a STRING_32 variable with the fetched content of the request. Currently the project has never referenced the cURL library either indirectly or directly. Rendering the code template in any class will result in code that cannot be compiled, unless the cURL library is reference by the project or library of a class where the template was rendered. This places the burden on the end-user to know they must include the cURL library to use a code template that fetches a URL's response content. The UI cue the user is presented with, such as the title and description may offer not indication of the library use or where to attain it, if the library is not available on their system. The code template could instead be written using the EiffelNet library, who knows?! In any case, the rendering of the template should result in the correct referencing of a required library or .NET assembly. In the future when an online repositories of libraries is available, any library unavailable locally can be downloaded.

There may also be the case where a library is already referenced by the project or library of a class where the code template is rendered, but the code template utilities an interface in a newer version of the library. In this case the project/library should be updated to include the newer version of the library.

<references>
  <library>
    <location>$ISE_LIBRARY/base/base.ecf</location>
  </library>
  <library>
    <uuid>6D7FF712-BBA5-4AC0-AABF-2D9880493A01</uuid>
    <version>5.7</version>
  </library>
  <assembly>
    <name>mscorlib</name>
    <version>2.0.54727</version>
    <culture>en-us</culture>
    <public>bb...</public>
  </assembly>
  <assembly>
    <name>System</name>
  </assembly>
</references>

Currently, supporting .NET, there are two types of library references; Eiffel library references, using library elements, and .NET assembly references, using assembly elements.

Both the library and assembly reference element can contain a variant amount of information, depending on how specific the reference should be.

Eiffel Library References

There are two ways to reference Eiffel libraries using the library element. The first, more direct, means is using an absolute location, or a "dollar" path as used in the configuration system. To use a location, the location should be used.

More indirectly, supporting the possibility of a library catalog and download-able libraries in the future, use the library UUID with the uuid element. Using a location agnostic locator for a library it may be necessary to specify a minimum version, ensuing the code template is compatible with the library. This can be specified using a version element, which matches up to the version information found in an ECF file.

Assembly Library References

Assembly references are specific to only .NET projects and are specified using the fusion name parts. name will always be required, as it is when attempting to load an assembly using the Common Language Runtime. All other parts are optional and will be used to narrow multiple matches; version indicates the minimum version of the assembly to, culture indicates the assembly located required when referencing an assembly and finally, key indicates the assembly's public key token, required to match any located assembly.

Code Template Declarations

In order to facilitate code templates, variables will be required to replaces parts of the template with user supplied parameters.

Literal Declarations

Literal code definitions types are declaration variables that can be replaced in a code template text. There are two forms of literal declarations; simple, editable declarations and functional literals that retrieve their value from an in-built function.

Every literal declaration is created using a literal element with an id attribute, defined using the Eiffel identifier rules ([a-zA-Z][a-zA-Z0-9_]*]), which will be used in a tokenized code template text block. id should contain a unique indentifer to the code template file, as not to conflict with any other declaration. Each literal will contain another optional Boolean attribute editable indicating if the literal declaration can be edited by the user. The editable attribute is another piece of code template information for the UI. It should indicate to the UI if the user is able to directly edit the variable or if the value is retrieve from a default or internally.

Basic

The most fundamental literal declarations should be simple to define. As already stated, the literal element should be used and the id attribute present. The editable attribute should also be applicable and effective even in the simplest of declarations.

Ever literal needs a value, as a suggestion, place holder or indication of the value. For instance, if the code template mechanism is integrated into the editor, the rendered template should highlight portions of the code template text to indicate declarations that can be replaced. If there is no suggested or default value then it is impossible to display any indication. Rendered programmatically there is still a need for a default value.

<literal id="var" editable="true">
<literal id="var" editable="true">
  <description>Editable literal.</description>
  <default>default value</default>
<literal>

Code Templates

The fundamental of code templates is the actual code template. The code template schema should not only support the specification of a template but also versioned templates.

It is necessary to version templates based on the compile version targeted or the current compiler in use. A long term vision of code templates is that they are not just prepackaged templates distributed with a release of EiffelStudio, but instead be distributed by first and third-parties. Even today, development houses run different version of EiffelStudio and may want to author their own code templates for in-house use with proprietary libraries.

Versioned Code Templates

As it may be necessary to tailor code templates to target specific versions of the compiler or even ECMA Eiffel, the code template schema should support multiple definitions of code templates tailored towards a minimum compiler version or a ECMA revision.

Versions will be matched against either the running version of the compiler or any future option for EiffelStudio and the compiler to target previous versions of the language/compiler, for the purpose of coding for backwards compatibility.

<templates>
  <template version="5.6">
    <![CDATA[${var}_set: ${var} = ${local}]]>
  </template>
 
  <template version="ECMA">
    <![CDATA[${var}_set: ${var} ~= ${local}]]>
  </template>
</templates>

In order to version a template, a version attribute should be used. The value should indicate the minimum version of the supported Eiffel compiler using the major.minor convention. For ECMA compatibility a special ECMA value can be used.

When using versions it may be required to fallback on an un-versioned code template. These are discussed next.

Because code templates can be version a template element needs to be nested within a templates element. The code template text itself can either be direct tokenize text or tokenize text wrapped in a <![CDATA[...]]> element, to avoid conflicts with the XML parser.

Un-versioned Code Templates

Un-versioned code templates are defined using the same convention as versioned code templates, sans the version attribute. As a result the author of the code snippet ensures the rendered template will compile will all versions of the Eiffel compiler introduced after a code template mechanism is implanted into the associated version of EiffelStudio.

The other un-versioned code template stipulation is there can only be one un-versioned code template. To define more than one leads to confusion as to which should be rendered. A mixture of versioned and un-versioned code templates should be permitted, retaining that only a single un-versioned template be defined. In the case of no matching minimum version, the un-versioned code template will be rendered.

<templates>
  <template>
    <![CDATA[${var}_attached: ${var} /= Void]]>
  </template>
</templates>

Because there is no minimum version specified for the template, regardless of the compiler used or targeted, the template will be rendered upon request.

Platform Dependent Templates

It will probably be necessary at some point to develop code templates that function for a specific platform or code generation target. For the simplification of the code template schema, platform segregation should be performed through organization of an installation. Currently this accomplished by the Eiffel compiler's built-in mechanism.

Contract Editor Requirements

Due to the fast approaching date of the 6.2 release, if implemented only a subset of code templates will be implemented for the contract editor. Below is an example of a code template written for a contract:

<?xml version="1.0"?>
<code_template format="1.0.0">
  <metadata>
    <title>Attached</title>
    <description>Code template for checking if an entity is attached.</description>
    <author>Eiffel Software</author>
    <categories>
      <category>contract</category>
    </categories>
    <shortcut>attached</shortcut>
  </metadata>
 
  <declarations>	
    <literal id="id"/>
  </declarations>
 
  <templates>
    <template>
      <![CDATA[${id}_attached: ${id} /= Void]]>
    </template>
  </templates>
 
</code_template>

Contracts should fully support the metadata section because the contract will need to produce a completion list of contracts, which will use the template's title. description is to ensure forward compatibility and will likely be used to describe the template in the completion UI. The shortcut element is expected to be utilized in 6.2 to quickly insert a contract using the contract editor tool's edition ability. categories is another future proofing addition and will probably not be respected in the release of 6.2. Post 6.2 however the category will be respected so those contracts without a category will not be available from the UI, because they do not fall into the contract category.

For the contract tool, only simple literal declarations will be supported, supporting the typed literals post the release of 6.2. No functions will be available for use yet.

For 6.2 code template versions will not be supported but the structuring for specifying code templates will be preserved for future proofing the contract code templates.

To ensure correct formatting and yet clarity of a code template declaration template delimiters can be used in a template declaration.

<templates>
    <template>
~#
code template
#~
    </template>
  </templates>

The template start (~#) and end (#~) delimiters can either be placed on their own line or placed before and after the template on the same line. In either case the trailing white-space after the start delimiter (~#) and the leading white-space before the end delimiter (#~) is removed. Without the delimiters all white-space is preserved.

To illustrate the semantics of the delimiters, consider the following template:

<templates>
    <template>
$var /= Void
    </template>
  </templates>

In Eiffel code would be

f
  do
    if | then
    end
  end

Inserting the template would result in the following code:

f
  do
    if
    var /= Void
        then
    end
  end

The template has inserted extra line breaks and white space before and after the actual template. To correct the template can be rewritten as follows:

<templates>
    <template>$var /= Void</template>
  </templates>

Or using delimiters:

<templates>
    <template>
 
~#
$var /= Void
#~
 
    </template>
  </templates>