webcomponents / webcomponents/custom-elements-manifest-tools
[RFC/discussion] tools API design
- Dominant language
- TypeScript
- Stars
- 12
- Forks
- 1
- Avg merge
- 3h 36m
- Merged PRs (30d)
- 1
Description
Copying most of this from my notes.
# Motivation
We should provide the core functionality already duplicated across the various
CEM projects in the wild.
# Proposed design
It seems we need a few areas of utilities:
- Type guards (e.g. `isClassDeclaration`)
- Traversal functions (various `find`-like functions mostly)
- Assertion functions (e.g. `exportHasCustomElementExport`)
- Getters (e.g. `getAllExportsOfKind`)
## Type guards
- `isJavaScriptModule`
- `isJavaScriptExport`
- `isCustomElementExport`
- `isDeclaration`
- `isCustomElementDeclaration`
- `isClassDeclaration`
- `isFunctionDeclaration`
- `isMixinDeclaration`
- `isVariableDeclaration`
- `isCustomElement`
- `isCustomElementDeclaration`
- `isCustomElementMixinDeclaration`
## Traversal functions
- `findParent(manifests, node, assertion)`
- Finds the first parent of the specified node which matches the assertion function
- `find(manifests, node, assertion)`
- Finds the first child which matches the assertion function
- `findAll(manifests, node, assertion)`
- Finds all children matching the assertion function
**TBD**
These traversal functions would be paired often with the type guards and assertion functions.
For example, `find(package, null, (n) => isJavaScriptExport(n))`.
## Assertion functions
**TBD**
## Getters
**TBD**
# Prior art
## CEM analyzer
- `getAllExportsOfKind`
- Filters the exports by a particular `kind`
- `getAllDeclarationsOfKind`
- Filters the declarations by a particular `kind`
- `getInheritanceTree`
- Gets the inheritance hierarchy of a given class name, as an array of
class names
- `getModuleFromManifests`
- Finds a particular module by `path` in a set of manifests
- `getModuleForClassLike`
- Finds a particular module's path which contains a class or mixin with the
specified name
- `getClassMemberDoc`
- Finds a class by name within a given module, then finds a member by name
within that class.
## CE language server
- `findClassForTagName`
- Finds the class from a set of manifests which has the specified tag name
associated with it
- `findCustomElementDeclarationFromModule`
- Finds the first custom element class declared in a given module
- `findDeclarationForTagName`
- Finds the custom element declaration from a set of manifests which
has the specified tag name associated with it
- `findCustomElementTagLike`
- Finds a registered tag which contains the specified string
- `getCustomElementTags`
- Finds all the registered tags from a set of manifests
- `findCustomElementDefinitionModule`
- Finds the module from a set of manifests which registered a given tag name
- `findTagNameForClass`
- Finds the tag name associated with the specified class name from a set of
manifests
- `moduleHasCustomElementExport`
- Determines if a module exports a custom element
- `exportHasCustomElementExport`
- Determines if an export is a custom element export
- `moduleHasCustomElementExportByName`
- Determines if a module exports the specified tag name
- `exportHascustomElementExportByName`
- Determines if an export is a custom element definition with a particular
name
- `findModuleByPath`
- Finds a module from a set of manifests which has the specified `path`
- `modulePathEquals`
- Determines if a module's path matches a given path
- `isCustomElementDeclaration`
- Determines if a declaration is a custom element declaration
## webcomponents.org
- `getCustomElements`
- Finds all custom elements exported by a given package, returning their
export and declaration amongst other things
- `getModule`
- Finds the module in a given package which has a path matching the one
specified
- `isClassDeclaration`
- Determines if a declaration is a class declaration
- `isFunctionDeclaration`
- Determines if a declaration is a function declaration
- `isMixinDeclaration`
- Determines if a declaration is a mixin declaration
- `isVariableDeclaration`
- Determines if a declaration is a variable declaration
- `isCustomElement`
- Determines if a declaration is a custom element declaration or a
custom element mixin declaration
- `isCustomElementDeclaration`
- Determines if a declaration is a custom element declaration
- `isCustomElementMixinDeclaration`
- Determines if a declaration is a custom element mixin declaration
- `resolveReference`
- Resolves a `Reference` to an actual `Module` from a set of manifests
# Open questions
## Type guards
- do we want to do what typescript did here and basically provide an `is*` function for every possibly type? e.g. we'd also have `isClassMethod`, `isAttribute`, etc etc.
## Traversals
- do we want these functions to consume `(manifest, nodeOrCallback, callback)`? im not such a fan or these messy overloads. but `(manifest, node|null, callback)` isn't much better. as in, you could traverse a manifest for something, or you could traverse a node within a manifest for something
- of course everything can be simplified to `find`/`findAll`, but do we also want to provide some higher level helpers? like `findExports`, `findDeclarations`, `findElement`, etc etc. we probably do otherwise this package won't reduce boilerplate/duplication much
cc @justinfagnani @matsuuu @rictic
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.