Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,22 @@ export const eventDecoratorsToStatic = (
}
};

/**
* Parse a single instance of Stencil's `@Event()` decorator and generate metadata for the class member that is
* decorated
* @param diagnostics a list of diagnostics used as a part of the parsing process. Any parse errors/warnings shall be
* added to this collection
* @param typeChecker an instance of the TypeScript type checker, used to generate information about the `@Event()` and
* its surrounding context in the AST
* @param prop the property on the Stencil component class that is decorated with `@Event()`
* @returns generated metadata for the class member decorated by `@Event()`, or `null` if none could be derived
*/
const parseEventDecorator = (
diagnostics: d.Diagnostic[],
typeChecker: ts.TypeChecker,
prop: ts.PropertyDeclaration
): d.ComponentCompilerStaticEvent => {
const eventDecorator = prop.decorators.find(isDecoratorNamed('Event'));
): d.ComponentCompilerStaticEvent | null => {
const eventDecorator = prop.decorators?.find(isDecoratorNamed('Event'));

if (eventDecorator == null) {
return null;
Expand Down Expand Up @@ -70,6 +80,12 @@ export const getEventName = (eventOptions: d.EventOptions, memberName: string) =
return memberName;
};

/**
* Derive Stencil's class member type metadata from a node in the AST
* @param typeChecker the TypeScript type checker
* @param node the node in the AST to generate metadata for
* @returns the generated metadata
*/
const getComplexType = (
typeChecker: ts.TypeChecker,
node: ts.PropertyDeclaration
Expand All @@ -83,6 +99,11 @@ const getComplexType = (
};
};

/**
* Derive the type of the event from the typings of `EventEmitter`
* @param type the AST node containing the `EventEmitter` typing
* @returns the type taken from `EventEmitter`, or `null` if the type cannot be derived
*/
const getEventType = (type: ts.TypeNode): ts.TypeNode | null => {
if (
ts.isTypeReferenceNode(type) &&
Expand All @@ -96,7 +117,18 @@ const getEventType = (type: ts.TypeNode): ts.TypeNode | null => {
return null;
};

const validateEventName = (diagnostics: d.Diagnostic[], node: ts.Node, eventName: string) => {
/**
* Helper function for validating the name of the event
*
* This function assumes that the name of the event has been determined prior to calling it
*
* @param diagnostics a list of diagnostics used as a part of the validation process. Any parse errors/warnings shall be
* added to this collection
* @param node the node in the AT containing the class member decorated with `@Event()`
* @param eventName the name of the event
*/
const validateEventName = (diagnostics: d.Diagnostic[], node: ts.Node, eventName: string): void => {
// this regex checks for a string that begins with a capital letter - e.g. 'AskJeeves', 'Zoo', 'Spotify'
if (/^[A-Z]/.test(eventName)) {
const diagnostic = buildWarn(diagnostics);
diagnostic.messageText = [
Expand All @@ -108,6 +140,7 @@ const validateEventName = (diagnostics: d.Diagnostic[], node: ts.Node, eventName
return;
}

// this regex checks for a string that begins 'on', followed by a capital letter - e.g. 'onAbout', 'onZing', 'onBlur'
if (/^on[A-Z]/.test(eventName)) {
const warn = buildWarn(diagnostics);
const suggestedEventName = eventName[2].toLowerCase() + eventName.slice(3);
Expand Down