Last active
August 10, 2017 16:18
-
-
Save tomdale/5dad6671d2621ec35d3ca4fee78742ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PDI lazy evaluation of webpack modules | |
// 1. during compile time, answering what is in scope | |
// 1a. if it is in scope, what is the fully qualified path? | |
// 2. compilation handle + metadata | |
// 3. please map this handle to a ComponentSpec (manager + definition) | |
// 4. please resolve (component name, referrer) into handle (for dynamic component helper) | |
// return wire format as metadata for compile step | |
// need to add hasComponentHelper | |
// DI feedback | |
type Specifier = [string, string]; | |
type AbsoluteSpecifier = [string, string, boolean]; | |
function specifierFor(type: string, name: string): Specifier { | |
return [type, name]; | |
} | |
function resolveSpecifier(specifier: Specifier, referrer: AbsoluteSpecifier, owner: Owner): AbsoluteSpecifier { | |
if (isAbsolute(specifier)) { return specifier; } | |
return owner.identify(specifier, referrer); | |
} | |
function isAbsolute(specifier: Specifier | AbsoluteSpecifier): specifier is AbsoluteSpecifier { | |
return !!specifier[2]; | |
} | |
type Handle = number; | |
/** | |
* Describes the results of compiling a single component's template. | |
*/ | |
interface CompilationResult { | |
/** | |
* The unique numerical identifier for this component. At runtime in the | |
* browser, the application will be asked to provide the Glimmer VM with the | |
* corresponding component manager and component definition for this handle. | |
*/ | |
handle: Handle; | |
/** | |
* Whether the template contained any uses of the `{{partial}}` helper. | |
*/ | |
hasEval: boolean; | |
/** | |
* Whether the template contained any dynamic invocations of the | |
* `{{component}}` helper. Note that this only includes *dynamic* use; for | |
* example, `{{component 'MyComponent'}}` can be resolved at compilation times | |
* and from the compiler perspective is identical to `<MyComponent />`. | |
*/ | |
hasDynamicComponentHelper: boolean; | |
} | |
/** | |
* Incrementally compiles component templates, building up a binary | |
* representation of the components of the entire application. | |
*/ | |
abstract class BundleCompiler { | |
abstract compile(templateSource: string, specifier: Specifier, delegate: CompilerDelegate): Handle; | |
} | |
interface CompilerDelegate { | |
/** | |
* During compilation, the compiler will ask the delegate about each component | |
* invocation found in the passed template. If the component exists in scope, | |
* the delegate should return `true`. If the component does not exist in | |
* scope, return `false`. (Note that returning `false` will cause the | |
* compilation process to fail.) | |
*/ | |
hasComponentInScope(componentName: string, referrer: Specifier): boolean; | |
/** | |
* If the delegate returns `true` from `hasComponentInScope()`, the compiler | |
* will next ask the delegate to turn the relative specifier into an | |
* globally-unique absolute specifier. By providing this unique identifier, | |
* the compiler avoids having to compile the same component multiple times if | |
* invoked from different locations. | |
*/ | |
resolveComponentSpecifier(componentName: string, referrer: Specifier): AbsoluteSpecifier; | |
} | |
// Contains component definition and component manager | |
interface ComponentSpec {} | |
abstract class Environment { | |
/** | |
* Provides the hydrated component spec for a given component's handle. | |
*/ | |
abstract resolveHandle(handle: Handle): ComponentSpec; | |
/** | |
* When the `{{component}}` helper is invoked dynamically, this method is | |
* called to convert the opaque user string into a `Handle` so the appropriate | |
* component can be created. | |
* | |
* The absolute specifier of the component where the helper was invoked is | |
* passed so that scoping rules can be applied. Depending on how dynamic the | |
* host environment is, additional data will need to be included at runtime to | |
* allow scoping rules to be resolved. | |
* | |
* Implementer Note: this means we will need to store the absolute specifier | |
* of the *invoking* component in the constants pool for templates that | |
* contain dynamic `{{component}}` helpers, so we can provide the referrer at | |
* runtime. | |
*/ | |
abstract handleForComponent(name: string, referrer: AbsoluteSpecifier): Handle; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment