Skip to content

Commit

Permalink
Mostly finished implementing improved logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Nov 9, 2024
1 parent 1a32e98 commit a9717f3
Show file tree
Hide file tree
Showing 20 changed files with 461 additions and 153 deletions.
4 changes: 4 additions & 0 deletions packages/@glimmer/debug/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export {
strip,
} from './lib/metadata';
export { opcodeMetadata } from './lib/opcode-metadata';
export type { IntoFragment } from './lib/render/fragment';
export { as, frag, Fragment, intoFragment } from './lib/render/fragment';
export { DebugLogger } from './lib/render/logger';
export {
check,
CheckArray,
Expand Down Expand Up @@ -42,6 +45,7 @@ export {
recordStackSize,
wrap,
} from './lib/stack-check';
export { type VmDiff, VmSnapshot, type VmSnapshotValueDiff } from './lib/vm/snapshot';

// Types are optimized await automatically
export type {
Expand Down
5 changes: 3 additions & 2 deletions packages/@glimmer/debug/lib/dism/opcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { exhausted } from '@glimmer/debug-util';
import { REFERENCE } from '@glimmer/reference';

import type { DisassembledOperand } from '../debug';
import type { ValueRefOptions } from '../render/basic';
import type { Fragment, IntoFragment } from '../render/fragment';
import type { RegisterName, SomeDisassembledOperand } from './dism';

Expand Down Expand Up @@ -154,7 +155,7 @@ export class SerializeBlockContext {
}
}

export function stackValue(element: unknown): Fragment {
export function stackValue(element: unknown, options?: ValueRefOptions): Fragment {
if (isReference(element)) {
return describeRef(element);
} else if (isCompilable(element)) {
Expand All @@ -176,7 +177,7 @@ export function stackValue(element: unknown): Fragment {
return frag` <${as.kw('template')} ${element.meta.moduleName ?? '(unknown module)'}>`;
}
} else {
return value(element);
return value(element, options);
}
}

Expand Down
22 changes: 12 additions & 10 deletions packages/@glimmer/debug/lib/render/basic.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Optional } from '@glimmer/interfaces';

import type { IntoFragment } from './fragment';
import type { LeafFragment } from './fragment-type';
import type { LeafFragment, ValueFragment } from './fragment-type';

import { Fragment, intoFragment } from './fragment';

Expand Down Expand Up @@ -43,24 +43,26 @@ export function join(frags: IntoFragment[], separator?: Optional<IntoFragment>):
return new Fragment({ kind: 'multi', value: output });
}

export function value(
value: unknown,
options?: { annotation: string } | { ref: string; value: IntoFragment }
): LeafFragment {
const normalize = () => {
export type ValueRefOptions = { annotation: string } | { ref: string; value?: IntoFragment };

export function value(val: unknown, options?: ValueRefOptions): LeafFragment {
const normalize = (): ValueFragment['display'] => {
if (options === undefined) return;

if ('annotation' in options) {
return { ref: options.annotation, value: intoFragment(options.annotation) };
return { ref: options.annotation, footnote: intoFragment(options.annotation) };
} else {
return { ref: options.ref, value: intoFragment(options.value) };
return {
ref: options.ref,
footnote: options.value ? intoFragment(options.value) : undefined,
};
}
};

return new Fragment({
kind: 'value',
value,
footnote: normalize(),
value: val,
display: normalize(),
});
}

Expand Down
12 changes: 10 additions & 2 deletions packages/@glimmer/debug/lib/render/buffer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { LogLine } from './entry';
import type { DisplayFragmentOptions, FlushedLines } from './logger';

import { ANNOTATION_STYLES } from './annotations';

/**
* The `LogFragmentBuffer` is responsible for collecting the fragments that are logged to the
* `DebugLogger` so that they can be accumulated during a group and flushed together.
Expand Down Expand Up @@ -74,6 +76,7 @@ export class LogFragmentBuffer {
*/
readonly #footnotes: QueuedEntry[] = [];
#nextFootnote = 1;
#style = 0;

constructor(options: DisplayFragmentOptions) {
this.#options = options;
Expand Down Expand Up @@ -102,12 +105,17 @@ export class LogFragmentBuffer {
* The `add` callback also takes a template string and an optional list of substitutions, which
* describe the way the footnote itself should be formatted.
*/
addFootnoted(subtle: boolean, add: (footnote: number, child: LogFragmentBuffer) => boolean) {
addFootnoted(
subtle: boolean,
add: (footnote: { n: number; style: string }, child: LogFragmentBuffer) => boolean
) {
if (subtle && !this.#options.showSubtle) return;

const child = new LogFragmentBuffer(this.#options);

const usedNumber = add(this.#nextFootnote, child);
const style = ANNOTATION_STYLES[this.#style++ % ANNOTATION_STYLES.length] as string;

const usedNumber = add({ n: this.#nextFootnote, style }, child);

if (usedNumber) {
this.#nextFootnote += 1;
Expand Down
8 changes: 6 additions & 2 deletions packages/@glimmer/debug/lib/render/combinators.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Fragment, IntoFragment } from './fragment';

import { group, join } from './basic';
import { frag, intoFragment } from './fragment';
import { as, frag, intoFragment } from './fragment';

/**
* The prepend function returns a subtle fragment if the contents are subtle.
Expand Down Expand Up @@ -98,6 +98,10 @@ export function array(
const contents = items.map((item) =>
isSubtle(item) ? frag`${map(item)}`.subtle() : map(item)
);
return wrap('[ ', join(contents, ', '), ' ]');
return wrap('[ ', join(contents, as.punct(', ')), ' ]');
}
}

export function ifSubtle(fragment: IntoFragment): Fragment {
return intoFragment(fragment).subtle();
}
5 changes: 4 additions & 1 deletion packages/@glimmer/debug/lib/render/fragment-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ export interface ValueFragment extends AbstractLeafFragment {
*
* The `display` property can be provided to override these defaults.
*/
readonly display?: { ref: string; footnote: Fragment } | { inline: Fragment } | undefined;
readonly display?:
| { ref: string; footnote?: Fragment | undefined }
| { inline: Fragment }
| undefined;
}

/**
Expand Down
50 changes: 29 additions & 21 deletions packages/@glimmer/debug/lib/render/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {
} from './fragment-type';
import type { DisplayFragmentOptions } from './logger';

import { ANNOTATION_STYLES } from './annotations';
import { LogFragmentBuffer } from './buffer';
import { formats } from './format';
import { FORMATTERS } from './fragment-type';
Expand Down Expand Up @@ -125,7 +124,7 @@ export class Fragment<T extends FragmentType = FragmentType> {
}

const fragment = this.#subtle(isSubtle);
return isSubtle ? fragment.styleAll('subtle') : fragment;
return isSubtle ? fragment.styleAll('dim') : fragment;
}

#subtle(isSubtle: boolean): Fragment<T> {
Expand Down Expand Up @@ -262,15 +261,15 @@ export class Fragment<T extends FragmentType = FragmentType> {
// Alternatively, if the value of a `value` fragment is `null` or `undefined`,
// append the string `null` or `undefined`, respectively with the `null` style.
} else if (fragment.value === null || fragment.value === undefined) {
Fragment.string('null', {
return Fragment.string('null', {
style: STYLES.null,
subtle: this.isSubtle(),
}).appendTo(buffer);

// Finally, if the value of a `value` fragment is boolean, append the string
// `true` or `false` with the `boolean` style.
} else if (typeof fragment.value === 'boolean') {
Fragment.string(String(fragment.value), {
return Fragment.string(String(fragment.value), {
style: STYLES.boolean,
subtle,
}).appendTo(buffer);
Expand Down Expand Up @@ -303,29 +302,36 @@ export class Fragment<T extends FragmentType = FragmentType> {
// footnote rather than the footnote number.
const override = fragment.kind === 'value' ? fragment.display : undefined;

buffer.addFootnoted(fragment.subtle ?? false, (n, footnote) => {
// Rotate the annotation styles so that the footnote references have different colors
const style = ANNOTATION_STYLES[n % ANNOTATION_STYLES.length] as string;
buffer.addFootnoted(fragment.subtle ?? false, ({ n, style }, footnote) => {
const appendValueAsFootnote = (ref: string) =>
footnote.append(
subtle,
`%c| %c[${ref}]%c ${FORMATTERS[fragment.kind]}`,
STYLES.dim,
style,
'',
fragment.value
);

if (override) {
if ('inline' in override) {
override.inline.subtle(subtle).appendTo(footnote);
return false;
}

buffer.append(subtle, `%c[${override.ref}]%c`, style, '');

if (override.footnote) {
frag`${as.dim('| ')}${override.footnote}`.subtle(subtle).appendTo(footnote);
} else {
buffer.append(subtle, `%c[${override.ref}]%c `, style, '');
override.footnote.subtle(subtle).appendTo(footnote);
appendValueAsFootnote(override.ref);
}
return false;
} else {
buffer.append(subtle, `%c[${n}]%c `, style, '');
footnote.append(
subtle,
`%c[${n}]%c ${FORMATTERS[fragment.kind]}`,
style,
'',
fragment.value
);
return true;
}

buffer.append(subtle, `%c[${n}]%c`, style, '');
appendValueAsFootnote(String(n));
return true;
});

break;
Expand Down Expand Up @@ -366,7 +372,9 @@ function intoLeafFragment(value: IntoLeafFragment): LeafFragment {
} else if (typeof value === 'number') {
return new Fragment({ kind: 'integer', value });
} else if (typeof value === 'string') {
if (/^[\s\p{P}]*$/u.test(value)) {
// If the string contains only whitespace and punctuation, we can treat it as a
// punctuation fragment.
if (/^[\s\p{P}\p{Sm}]*$/u.test(value)) {
return new Fragment({ kind: 'string', value, style: STYLES.punct });
} else {
return new Fragment({ kind: 'string', value });
Expand All @@ -393,7 +401,7 @@ export function frag(strings: TemplateStringsArray, ...values: IntoFragment[]):
export const as = Object.fromEntries(
Object.entries(STYLES).map(([k, v]) => [
k,
(value: IntoFragment) => intoFragment(value).styleAll({ style: v }),
(value: IntoFragment): Fragment => intoFragment(value).styleAll({ style: v }),
])
) as {
[K in keyof typeof STYLES]: ((value: IntoLeafFragment) => LeafFragment) &
Expand Down
8 changes: 6 additions & 2 deletions packages/@glimmer/debug/lib/render/logger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { LOCAL_LOGGER } from '@glimmer/util';
import { getFlagValues } from '@glimmer/local-debug-flags';
import { getFlagValues, LOCAL_SUBTLE_LOGGING } from '@glimmer/local-debug-flags';
import { LOCAL_LOGGER } from '@glimmer/util';

import type { LogEntry, LogLine } from './entry';
import type { IntoFormat } from './format';
Expand All @@ -15,6 +15,10 @@ export interface DisplayFragmentOptions {
export type FlushedLines = [LogLine, ...LogEntry[]];

export class DebugLogger {
static configured() {
return new DebugLogger(LOCAL_LOGGER, { showSubtle: !!LOCAL_SUBTLE_LOGGING });
}

readonly #logger: typeof LOCAL_LOGGER;
readonly #options: DisplayFragmentOptions;

Expand Down
8 changes: 6 additions & 2 deletions packages/@glimmer/debug/lib/render/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const STYLES = {
token: 'color: green',
def: 'color: blue',
builtin: 'color: blue',
punct: 'color: grey',
punct: 'color: GrayText',
kw: 'color: rgb(185 0 99 / 100%);',
type: 'color: teal',
number: 'color: blue',
Expand All @@ -24,9 +24,13 @@ export const STYLES = {
meta: 'color: grey',
register: 'color: purple',
constant: 'color: purple',
subtle: 'color: lightgrey',
dim: 'color: lightgrey',
internals: 'color: lightgrey; font-style: italic',

diffAdd: 'color: Highlight',
diffDelete: 'color: SelectedItem',
diffChange: 'color: MarkText; background-color: Mark',

sublabel: 'font-style: italic; color: grey',
error: 'color: red',
label: 'text-decoration: underline',
Expand Down
Loading

0 comments on commit a9717f3

Please sign in to comment.