Import Statement
From OpenLaszlo
Contents |
Overview
This is a proposal for a new tag, <import>, which is intended to eventaully replace the use of <include> to include statically linked libraries and to enable a number of other features, starting with dynamic libraries in OpenLaszlo 3.0.
Dynamic Libraries specifies a subset of this syntax that was implemented in OpenLaszlo 3.0. It lists the requirements for the "dynamic library" feature, which uses this syntax.
The other features that the import statement is intended to eventually support include:
- Runtime Shared Libraries
- Sharing portions of a compiled program among applications, to amortize download size across multiple applications
- Binary distribution
- Binary distribution of the artifacts that correspond to separable source units, for compilation speed and IP protection
- Namespaces
- The creation of XML and JavaScript namespaces
These features hang together because they relate to separate processing (compilation, linking, or downloading) of application modules, and have been proven to be properties of a unified concept by the existence of coherent features that provide this set of features.
Non-goals are:
- Separate compilation, for compilation speed — this might become a goal
- Execution-time discovery and retrieval of resources including code — an extension of the JavaScript API in Dynamic Libraries would be more appropriate for this; it doesn't need a declarative interface based on <import>
Requirements
- [TBD: namespace, runtime shared libraries, binary distribution]
- The design MUST implementable in the Flash 6 runtime.
- The design MUST implementable for a non-Flash JavaScript target.
- The design SHOULD be compatible with other XML programming systems (XLST, RELAX NG, ...)
Also see the dynamic library requirements.
Definitions
- An element is at the top level of an application if it is an immediate child of the <canvas> or <library> root document element of an application source file.
Syntax
This proposal introduces a new tag, the <import> tag. This tag must occur at the top level of an application. The "href" attribute of an import statement is the pathname of a library file. The pathname is resolved relative to the pathname of the file that contains the import statement.
The syntax of the import tag is as follows:
<import href="mylib.lzx" prefix="ns" stage="late"/>
All attributes except href are optional. The <import> tag has these attributes:
| Name | Type | Default | Description |
|---|---|---|---|
| href | URI | required | The URI of a file that defines the library. In the case where stage is compile (the default), this has the same meaning as it does in an <include> tag. If stage="deferred", the URI is resolved relative to the location of the location of the file that contains the <import> element, and a request for this URI is sent to the server to request a library file that is downloaded into the running application.
|
| stage | "late" | "defer" | compile | If stage is "normal", the contents of the library are linked into the application at compile time. If it is "defer", the statement defines an object whose name is the value of the name attribute, and that can be used to load the library during the execution of the application via the API specified in Dynamic Libraries. |
| name | JavaScript identifier | global | If this is is not empty, it is the name of an ECMAScript object whose properties are the global ECMAScript names (classes, functions, objects) that the library defines. If it is not empty and is the name of a namespace prefix that the including file defines with a xmlns or xmlns:prefix attribute, tag names such as myclass that the library defines are accessible outside the library as prefix myclass. |
| prefix | XML namespace prefix | "" | If this is not empty, it must be an XML Namespace prefix that is in scope on the <import> element. In this case, class definitions in the target library are bound to XML tags in the specified namespace. See the section on Namespaces below. |
| onload, onerror, ontimeout | JavaScript statements | empty |
Namespaces
Import a tag in a namespace:
<canvas xmlns:ns="urn:myns"> <import prefix="ns" href="mylib.lzx"/> <ns:test/> </canvas> <library> <class name="test" extends="text">Hello!</class> </library>
Define a tag with the same unqualified name as a builtin (autoincluded) tag:
<canvas xmlns:ns="urn:myns"> <import prefix="ns" href="mybutton.lzx"/> <button>Built-in Button</button> <ns:button/> </canvas> <library> <class name="button" extends="text">My Button</class> </library>
Define two tags with the same unqualified name:
<canvas xmlns:ns1="urn:myns1" xmlns:ns2="urn:myns1"> <import prefix="ns1" href="lib1.lzx"/> <import prefix="ns2" href="lib2.lzx"/> <ns1:test/> <ns2:test/> </canvas> <library> <class name="test" extends="text">lib1</class> </library> <library> <class name="test" extends="text">lib2</class> </library>
TBD: Specify how this interacts with multiple files; how resolution is done at compile and runtime.
Issue; This looks very natural for XML, but is fairly different from Java. Should the URL be present in the library instead, like a tag library or a Java package source?
Rationale
The distinction between <include> and <import> is similar to that in XSLT and RELAX NG, and to the distinction between #include in languages such as C, C++, and m4, and import in languages such as Java, JavaScript 2.0, and Python. [Details TBD.]
Staged Implementation
The features that use the <import> statement API can be implemented in any order.
Dynamic Libraries
During this stage, the stage and name attributes are required. The stage must be one of "late" and "defer" ("compile" is not allowed).
Dynamic Libraries describes this stage in more detail.
Runtime Shared Libraries
This implementation stage may not require any API changes. It requires a reimplementation of the library compilation mechanism to avoid making the library specific to the canvas.
Binary Distribution
This stage adds support for stage="compile" if it is not already present, and may remove the requirement for the name attribute.
The implementation requires the creation of a metadata file that can be used to compile an application that includes a library.
Deprecating Include
The <import> tag is eventually intended to replace the use of <include> to import libraries. At some point, we would deprecate <include> with a library target and only use <import> instead, and add an option to <import> that specifies whether its target is statically linked or dynamically linked. This brings LZX more into line with the way that other platforms --- Java, JavaScript, Python, XSLT --- use the 'import' keyword or tag, and it allows the developer to make a minimal change --- the value of an attribute --- to toggle between static and dynamic linking of a library. The use of <import> with a <library> target is best understood in the context of this language evolution.
This stage adds support for stage="compile" if it is not already present, and removes the requirement for the name attribute.
Namespaces
This adds support for the prefix attribute.
Test Cases
- static import; global namespace; URI is known at compile time
- static import; local namespace; URI is known at compile time
- dynamic import; global namespace; URI is known at compile time
- dynamic import; local namespace; URI is known at compile time
- two libraries; static imports; class is defined in both
- static local import; namespace has different prefixes at different points
- global local import; namespace has different prefixes at different points
- computed URI; local import
- computed URI; global import
Appendix
Dynamically loaded libraries exist in these systems (and many more):
- SOM (Shared Object Manager) files on the Classic MacOS
- C/C++/assembly .so files on Linux
- Windows .dll files
- Java .class and .jar files
- CLR assemblies
- Lisp files
- Python files

