webcomponents / webcomponents/custom-elements-manifest-tools

[RFC/discussion] tools API design

Open
#2 8 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.