Skip to content

Commit 4cc013f

Browse files
committed
centralise stuff
1 parent 34e8562 commit 4cc013f

File tree

8 files changed

+88
-167
lines changed

8 files changed

+88
-167
lines changed

packages/svelte/src/compiler/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { remove_typescript_nodes } from './phases/1-parse/remove_typescript_node
88
import { analyze_component, analyze_module } from './phases/2-analyze/index.js';
99
import { transform_component, transform_module } from './phases/3-transform/index.js';
1010
import { validate_component_options, validate_module_options } from './validate-options.js';
11+
import { reset_warnings } from './warnings.js';
1112
export { default as preprocess } from './preprocess/index.js';
1213

1314
/**
@@ -20,6 +21,7 @@ export { default as preprocess } from './preprocess/index.js';
2021
*/
2122
export function compile(source, options) {
2223
try {
24+
const warnings = reset_warnings({ source, filename: options.filename });
2325
const validated = validate_component_options(options, '');
2426
let parsed = _parse(source);
2527

@@ -44,6 +46,7 @@ export function compile(source, options) {
4446
const analysis = analyze_component(parsed, source, combined_options);
4547

4648
const result = transform_component(analysis, source, combined_options);
49+
result.warnings = warnings;
4750
result.ast = to_public_ast(source, parsed, options.modernAst);
4851
return result;
4952
} catch (e) {
@@ -65,9 +68,12 @@ export function compile(source, options) {
6568
*/
6669
export function compileModule(source, options) {
6770
try {
71+
const warnings = reset_warnings({ source, filename: options.filename });
6872
const validated = validate_module_options(options, '');
6973
const analysis = analyze_module(parse_acorn(source, false), validated);
70-
return transform_module(analysis, source, validated);
74+
const result = transform_module(analysis, source, validated);
75+
result.warnings = warnings;
76+
return result;
7177
} catch (e) {
7278
if (e instanceof CompileError) {
7379
handle_compile_error(e, options.filename, source);

packages/svelte/src/compiler/phases/2-analyze/a11y.js

Lines changed: 37 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -672,15 +672,6 @@ function check_element(node, state) {
672672
// foreign namespace means elements can have completely different meanings, therefore we don't check them
673673
if (state.options.namespace === 'foreign') return;
674674

675-
/**
676-
* @template {keyof import('../../warnings-tmp.js').AllWarnings} T
677-
* @param {{ start?: number, end?: number }} node
678-
* @param {T} code
679-
* @param {Parameters<import('../../warnings-tmp.js').AllWarnings[T]>} args
680-
* @returns {void}
681-
*/
682-
const push_warning = (node, code, ...args) => warn(state.analysis.warnings, node, code, ...args);
683-
684675
/** @type {Map<string, import('#compiler').Attribute>} */
685676
const attribute_map = new Map();
686677

@@ -727,17 +718,17 @@ function check_element(node, state) {
727718
if (name.startsWith('aria-')) {
728719
if (invisible_elements.includes(node.name)) {
729720
// aria-unsupported-elements
730-
push_warning(attribute, 'a11y-aria-attributes', node.name);
721+
warn(attribute, 'a11y-aria-attributes', node.name);
731722
}
732723

733724
const type = name.slice(5);
734725
if (!aria_attributes.includes(type)) {
735726
const match = fuzzymatch(type, aria_attributes);
736-
push_warning(attribute, 'a11y-unknown-aria-attribute', type, match);
727+
warn(attribute, 'a11y-unknown-aria-attribute', type, match);
737728
}
738729

739730
if (name === 'aria-hidden' && regex_heading_tags.test(node.name)) {
740-
push_warning(attribute, 'a11y-hidden', node.name);
731+
warn(attribute, 'a11y-hidden', node.name);
741732
}
742733

743734
// aria-proptypes
@@ -747,7 +738,7 @@ function check_element(node, state) {
747738
if (value !== null && value !== undefined) {
748739
const schema = aria.get(/** @type {import('aria-query').ARIAProperty} */ (name));
749740
if (schema !== undefined && !is_valid_aria_attribute_value(schema, value)) {
750-
push_warning(attribute, 'a11y-incorrect-aria-attribute-type', schema, name);
741+
warn(attribute, 'a11y-incorrect-aria-attribute-type', schema, name);
751742
}
752743
}
753744

@@ -758,15 +749,15 @@ function check_element(node, state) {
758749
!is_interactive_element(node.name, attribute_map) &&
759750
!attribute_map.has('tabindex')
760751
) {
761-
push_warning(attribute, 'a11y-aria-activedescendant-has-tabindex');
752+
warn(attribute, 'a11y-aria-activedescendant-has-tabindex');
762753
}
763754
}
764755

765756
// aria-role
766757
if (name === 'role') {
767758
if (invisible_elements.includes(node.name)) {
768759
// aria-unsupported-elements
769-
push_warning(attribute, 'a11y-misplaced-role', node.name);
760+
warn(attribute, 'a11y-misplaced-role', node.name);
770761
}
771762

772763
const value = get_static_value(attribute);
@@ -776,10 +767,10 @@ function check_element(node, state) {
776767
/** @type {import('aria-query').ARIARoleDefinitionKey} current_role */ (c_r);
777768

778769
if (current_role && is_abstract_role(current_role)) {
779-
push_warning(attribute, 'a11y-no-abstract-role', current_role);
770+
warn(attribute, 'a11y-no-abstract-role', current_role);
780771
} else if (current_role && !aria_roles.includes(current_role)) {
781772
const match = fuzzymatch(current_role, aria_roles);
782-
push_warning(attribute, 'a11y-unknown-role', current_role, match);
773+
warn(attribute, 'a11y-unknown-role', current_role, match);
783774
}
784775

785776
// no-redundant-roles
@@ -788,7 +779,7 @@ function check_element(node, state) {
788779
// <ul role="list"> is ok because CSS list-style:none removes the semantics and this is a way to bring them back
789780
!['ul', 'ol', 'li'].includes(node.name)
790781
) {
791-
push_warning(attribute, 'a11y-no-redundant-roles', current_role);
782+
warn(attribute, 'a11y-no-redundant-roles', current_role);
792783
}
793784

794785
// Footers and headers are special cases, and should not have redundant roles unless they are the children of sections or articles.
@@ -797,7 +788,7 @@ function check_element(node, state) {
797788
const has_nested_redundant_role =
798789
current_role === a11y_nested_implicit_semantics.get(node.name);
799790
if (has_nested_redundant_role) {
800-
push_warning(attribute, 'a11y-no-redundant-roles', current_role);
791+
warn(attribute, 'a11y-no-redundant-roles', current_role);
801792
}
802793
}
803794

@@ -813,7 +804,7 @@ function check_element(node, state) {
813804
(prop) => !attributes.find((a) => a.name === prop)
814805
);
815806
if (has_missing_props) {
816-
push_warning(
807+
warn(
817808
attribute,
818809
'a11y-role-has-required-aria-props',
819810
current_role,
@@ -836,7 +827,7 @@ function check_element(node, state) {
836827
a11y_interactive_handlers.includes(handler)
837828
);
838829
if (has_interactive_handlers) {
839-
push_warning(node, 'a11y-interactive-supports-focus', current_role);
830+
warn(node, 'a11y-interactive-supports-focus', current_role);
840831
}
841832
}
842833

@@ -845,7 +836,7 @@ function check_element(node, state) {
845836
is_interactive_element(node.name, attribute_map) &&
846837
(is_non_interactive_roles(current_role) || is_presentation_role(current_role))
847838
) {
848-
push_warning(
839+
warn(
849840
node,
850841
'a11y-no-interactive-element-to-noninteractive-role',
851842
current_role,
@@ -861,7 +852,7 @@ function check_element(node, state) {
861852
current_role
862853
)
863854
) {
864-
push_warning(
855+
warn(
865856
node,
866857
'a11y-no-noninteractive-element-to-interactive-role',
867858
current_role,
@@ -874,25 +865,25 @@ function check_element(node, state) {
874865

875866
// no-access-key
876867
if (name === 'accesskey') {
877-
push_warning(attribute, 'a11y-accesskey');
868+
warn(attribute, 'a11y-accesskey');
878869
}
879870

880871
// no-autofocus
881872
if (name === 'autofocus') {
882-
push_warning(attribute, 'a11y-autofocus');
873+
warn(attribute, 'a11y-autofocus');
883874
}
884875

885876
// scope
886877
if (name === 'scope' && !is_dynamic_element && node.name !== 'th') {
887-
push_warning(attribute, 'a11y-misplaced-scope');
878+
warn(attribute, 'a11y-misplaced-scope');
888879
}
889880

890881
// tabindex-no-positive
891882
if (name === 'tabindex') {
892883
const value = get_static_value(attribute);
893884
// @ts-ignore todo is tabindex=true correct case?
894885
if (!isNaN(value) && +value > 0) {
895-
push_warning(attribute, 'a11y-positive-tabindex');
886+
warn(attribute, 'a11y-positive-tabindex');
896887
}
897888
}
898889
}
@@ -916,7 +907,7 @@ function check_element(node, state) {
916907
const has_key_event =
917908
handlers.has('keydown') || handlers.has('keyup') || handlers.has('keypress');
918909
if (!has_key_event) {
919-
push_warning(node, 'a11y-click-events-have-key-events');
910+
warn(node, 'a11y-click-events-have-key-events');
920911
}
921912
}
922913
}
@@ -934,7 +925,7 @@ function check_element(node, state) {
934925
const tab_index = attribute_map.get('tabindex');
935926
const tab_index_value = get_static_text_value(tab_index);
936927
if (tab_index && (tab_index_value === null || Number(tab_index_value) >= 0)) {
937-
push_warning(node, 'a11y-no-noninteractive-tabindex');
928+
warn(node, 'a11y-no-noninteractive-tabindex');
938929
}
939930
}
940931

@@ -949,14 +940,7 @@ function check_element(node, state) {
949940
if (
950941
invalid_aria_props.includes(/** @type {import('aria-query').ARIAProperty} */ (attr.name))
951942
) {
952-
push_warning(
953-
attr,
954-
'a11y-role-supports-aria-props',
955-
attr.name,
956-
role_value,
957-
is_implicit,
958-
node.name
959-
);
943+
warn(attr, 'a11y-role-supports-aria-props', attr.name, role_value, is_implicit, node.name);
960944
}
961945
}
962946
}
@@ -974,7 +958,7 @@ function check_element(node, state) {
974958
a11y_recommended_interactive_handlers.includes(handler)
975959
);
976960
if (has_interactive_handlers) {
977-
push_warning(node, 'a11y-no-noninteractive-element-interactions', node.name);
961+
warn(node, 'a11y-no-noninteractive-element-interactions', node.name);
978962
}
979963
}
980964

@@ -993,16 +977,16 @@ function check_element(node, state) {
993977
a11y_interactive_handlers.includes(handler)
994978
);
995979
if (interactive_handlers.length > 0) {
996-
push_warning(node, 'a11y-no-static-element-interactions', node.name, interactive_handlers);
980+
warn(node, 'a11y-no-static-element-interactions', node.name, interactive_handlers);
997981
}
998982
}
999983

1000984
if (handlers.has('mouseover') && !handlers.has('focus')) {
1001-
push_warning(node, 'a11y-mouse-events-have-key-events', 'mouseover', 'focus');
985+
warn(node, 'a11y-mouse-events-have-key-events', 'mouseover', 'focus');
1002986
}
1003987

1004988
if (handlers.has('mouseout') && !handlers.has('blur')) {
1005-
push_warning(node, 'a11y-mouse-events-have-key-events', 'mouseout', 'blur');
989+
warn(node, 'a11y-mouse-events-have-key-events', 'mouseout', 'blur');
1006990
}
1007991

1008992
// element-specific checks
@@ -1021,22 +1005,22 @@ function check_element(node, state) {
10211005
const href_value = get_static_text_value(href);
10221006
if (href_value !== null) {
10231007
if (href_value === '' || href_value === '#' || /^\W*javascript:/i.test(href_value)) {
1024-
push_warning(href, 'a11y-invalid-attribute', href.name, href_value);
1008+
warn(href, 'a11y-invalid-attribute', href.name, href_value);
10251009
}
10261010
}
10271011
} else if (!has_spread) {
10281012
const id_attribute = get_static_value(attribute_map.get('id'));
10291013
const name_attribute = get_static_value(attribute_map.get('name'));
10301014
if (!id_attribute && !name_attribute) {
1031-
push_warning(...warn_missing_attribute(node, ['href']));
1015+
warn(...warn_missing_attribute(node, ['href']));
10321016
}
10331017
}
10341018
} else if (!has_spread) {
10351019
const required_attributes = a11y_required_attributes[node.name];
10361020
if (required_attributes) {
10371021
const has_attribute = required_attributes.some((name) => attribute_map.has(name));
10381022
if (!has_attribute) {
1039-
push_warning(...warn_missing_attribute(node, required_attributes));
1023+
warn(...warn_missing_attribute(node, required_attributes));
10401024
}
10411025
}
10421026
}
@@ -1048,15 +1032,15 @@ function check_element(node, state) {
10481032
const required_attributes = ['alt', 'aria-label', 'aria-labelledby'];
10491033
const has_attribute = required_attributes.some((name) => attribute_map.has(name));
10501034
if (!has_attribute) {
1051-
push_warning(...warn_missing_attribute(node, required_attributes, 'input type="image"'));
1035+
warn(...warn_missing_attribute(node, required_attributes, 'input type="image"'));
10521036
}
10531037
}
10541038
// autocomplete-valid
10551039
const autocomplete = attribute_map.get('autocomplete');
10561040
if (type && autocomplete) {
10571041
const autocomplete_value = get_static_value(autocomplete);
10581042
if (!is_valid_autocomplete(autocomplete_value)) {
1059-
push_warning(autocomplete, 'a11y-autocomplete-valid', type_value, autocomplete_value);
1043+
warn(autocomplete, 'a11y-autocomplete-valid', type_value, autocomplete_value);
10601044
}
10611045
}
10621046
}
@@ -1066,7 +1050,7 @@ function check_element(node, state) {
10661050
const aria_hidden = get_static_value(attribute_map.get('aria-hidden'));
10671051
if (alt_attribute && !aria_hidden) {
10681052
if (/\b(image|picture|photo)\b/i.test(alt_attribute)) {
1069-
push_warning(node, 'a11y-img-redundant-alt');
1053+
warn(node, 'a11y-img-redundant-alt');
10701054
}
10711055
}
10721056
}
@@ -1096,7 +1080,7 @@ function check_element(node, state) {
10961080
return has;
10971081
};
10981082
if (!attribute_map.has('for') && !has_input_child(node)) {
1099-
push_warning(node, 'a11y-label-has-associated-control');
1083+
warn(node, 'a11y-label-has-associated-control');
11001084
}
11011085
}
11021086

@@ -1118,13 +1102,13 @@ function check_element(node, state) {
11181102
);
11191103
}
11201104
if (!has_caption) {
1121-
push_warning(node, 'a11y-media-has-caption');
1105+
warn(node, 'a11y-media-has-caption');
11221106
}
11231107
}
11241108

11251109
if (node.name === 'figcaption') {
11261110
if (!is_parent(node.parent, ['figure'])) {
1127-
push_warning(node, 'a11y-structure', true);
1111+
warn(node, 'a11y-structure', true);
11281112
}
11291113
}
11301114

@@ -1138,13 +1122,13 @@ function check_element(node, state) {
11381122
(child) => child.type === 'RegularElement' && child.name === 'figcaption'
11391123
);
11401124
if (index !== -1 && index !== 0 && index !== children.length - 1) {
1141-
push_warning(children[index], 'a11y-structure', false);
1125+
warn(children[index], 'a11y-structure', false);
11421126
}
11431127
}
11441128

11451129
if (a11y_distracting_elements.includes(node.name)) {
11461130
// no-distracting-elements
1147-
push_warning(node, 'a11y-distracting-elements', node.name);
1131+
warn(node, 'a11y-distracting-elements', node.name);
11481132
}
11491133

11501134
// Check content
@@ -1154,7 +1138,7 @@ function check_element(node, state) {
11541138
a11y_required_content.includes(node.name) &&
11551139
node.fragment.nodes.length === 0
11561140
) {
1157-
push_warning(node, 'a11y-missing-content', node.name);
1141+
warn(node, 'a11y-missing-content', node.name);
11581142
}
11591143
}
11601144

packages/svelte/src/compiler/phases/2-analyze/css/css-warn.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ import { is_keyframes_node } from '../../css.js';
44

55
/**
66
* @param {import('#compiler').Css.StyleSheet} stylesheet
7-
* @param {import('../../types.js').RawWarning[]} warnings
87
*/
9-
export function warn_unused(stylesheet, warnings) {
10-
walk(stylesheet, { warnings, stylesheet }, visitors);
8+
export function warn_unused(stylesheet) {
9+
walk(stylesheet, { stylesheet }, visitors);
1110
}
1211

13-
/** @type {import('zimmerframe').Visitors<import('#compiler').Css.Node, { warnings: import('../../types.js').RawWarning[], stylesheet: import('#compiler').Css.StyleSheet }>} */
12+
/** @type {import('zimmerframe').Visitors<import('#compiler').Css.Node, { stylesheet: import('#compiler').Css.StyleSheet }>} */
1413
const visitors = {
1514
Atrule(node, context) {
1615
if (!is_keyframes_node(node)) {
@@ -26,7 +25,7 @@ const visitors = {
2625
if (!node.metadata.used) {
2726
const content = context.state.stylesheet.content;
2827
const text = content.styles.substring(node.start - content.start, node.end - content.start);
29-
warn(context.state.warnings, node, 'css-unused-selector', text);
28+
warn(node, 'css-unused-selector', text);
3029
}
3130

3231
context.next();

0 commit comments

Comments
 (0)