chrome-devtools-frontend 1.0.997598 → 1.0.998045
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/docs/design_guidelines.md +1 -1
- package/front_end/core/i18n/locales/en-US.json +0 -192
- package/front_end/core/i18n/locales/en-XL.json +0 -192
- package/front_end/entrypoints/main/MainImpl.ts +1 -1
- package/front_end/models/bindings/BreakpointManager.ts +15 -0
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +9 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +13 -0
- package/front_end/models/issues_manager/DeprecationIssue.ts +186 -184
- package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +1 -1
- package/front_end/panels/css_overview/components/CSSOverviewStartView.ts +1 -1
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +1 -1
- package/front_end/ui/legacy/themeColors.css +2 -0
- package/front_end/ui/legacy/toolbar.css +5 -1
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/lit_template_result_or_nothing.js +140 -0
- package/scripts/eslint_rules/lib/no_only_eslint_tests.js +5 -1
- package/scripts/eslint_rules/tests/lit_template_result_or_nothing_test.js +133 -0
- package/scripts/hosted_mode/server.js +1 -1
@@ -0,0 +1,140 @@
|
|
1
|
+
// Copyright 2020 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
'use strict';
|
5
|
+
|
6
|
+
module.exports = {
|
7
|
+
meta: {
|
8
|
+
type: 'problem',
|
9
|
+
|
10
|
+
docs: {
|
11
|
+
description: 'Enforce use of LitHtml.LitTemplate type rather than union with LitHtml.nothing',
|
12
|
+
category: 'Possible Errors',
|
13
|
+
},
|
14
|
+
fixable: 'code',
|
15
|
+
messages: {
|
16
|
+
useLitTemplateOverEmptyObject:
|
17
|
+
'Prefer LitHtml.LitTemplate type over a union with {}',
|
18
|
+
useLitTemplateOverTypeOfNothing:
|
19
|
+
'Prefer LitHtml.LitTemplate type over a union with LitHtml.nothing',
|
20
|
+
},
|
21
|
+
schema: [] // no options
|
22
|
+
},
|
23
|
+
create: function(context) {
|
24
|
+
const sourceCode = context.getSourceCode();
|
25
|
+
const UNION_TYPE_FOR_LIT_TEMPLATE = 'LitHtml.LitTemplate';
|
26
|
+
|
27
|
+
function checkUnionReturnTypeForLit(node) {
|
28
|
+
// We want to go through the types in the union and match if:
|
29
|
+
// 1. We find `LitHtml.TemplateResult` and `{}`
|
30
|
+
// 2. We find `LitHtml.TemplateResult` and `LitHtml.nothing`.
|
31
|
+
// Otherwise, this node is OK.
|
32
|
+
|
33
|
+
let templateResultNode = null;
|
34
|
+
let literalEmptyObjectNode = null;
|
35
|
+
let litNothingNode = null;
|
36
|
+
|
37
|
+
const nonLitRelatedNodesInUnion = new Set();
|
38
|
+
|
39
|
+
for (const typeNode of node.types) {
|
40
|
+
// This matches a type reference of X.y. Now we see if X === 'LitHtml' and y === 'TemplateResult'
|
41
|
+
if (typeNode.type === 'TSTypeReference' && typeNode.typeName.type === 'TSQualifiedName') {
|
42
|
+
const leftText = typeNode.typeName.left.name;
|
43
|
+
const rightText = typeNode.typeName.right.name;
|
44
|
+
if (leftText === 'LitHtml' && rightText === 'TemplateResult') {
|
45
|
+
templateResultNode = typeNode;
|
46
|
+
continue;
|
47
|
+
}
|
48
|
+
} else if (typeNode.type === 'TSTypeLiteral') {
|
49
|
+
// The TSTypeLiteral type matches against the literal `{}` type.
|
50
|
+
literalEmptyObjectNode = typeNode;
|
51
|
+
continue;
|
52
|
+
} else if (typeNode.type === 'TSTypeQuery' && typeNode.exprName.type === 'TSQualifiedName') {
|
53
|
+
// matches `typeof X.y`
|
54
|
+
const leftText = typeNode.exprName.left.name;
|
55
|
+
const rightText = typeNode.exprName.right.name;
|
56
|
+
if (leftText === 'LitHtml' && rightText === 'nothing') {
|
57
|
+
litNothingNode = typeNode;
|
58
|
+
continue;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
nonLitRelatedNodesInUnion.add(typeNode);
|
63
|
+
}
|
64
|
+
|
65
|
+
// We didn't find LitHtml.TemplateResult, so bail.
|
66
|
+
if (!templateResultNode) {
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
|
70
|
+
if (!litNothingNode && !literalEmptyObjectNode) {
|
71
|
+
// We found TemplateResult with no `typeof LitHtml.nothing` or `{}`, so
|
72
|
+
// bail.
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
76
|
+
// If we found a union type of:
|
77
|
+
// LitHtml.TemplateResult|{}|number
|
78
|
+
// That needs to become:
|
79
|
+
// LitHtml.LitTemplate|number
|
80
|
+
// So we capture all the non-lit related types in the union, and get
|
81
|
+
// their text content, so we can keep them around when we run the fixer.
|
82
|
+
const nonLitRelatedTypesToKeep = Array.from(nonLitRelatedNodesInUnion, node => {
|
83
|
+
return sourceCode.getText(node);
|
84
|
+
});
|
85
|
+
const newText = [UNION_TYPE_FOR_LIT_TEMPLATE, ...nonLitRelatedTypesToKeep].join('|');
|
86
|
+
|
87
|
+
context.report({
|
88
|
+
node,
|
89
|
+
messageId: litNothingNode ? 'useLitTemplateOverTypeOfNothing' : 'useLitTemplateOverEmptyObject',
|
90
|
+
fix(fixer) {
|
91
|
+
return fixer.replaceText(node, newText);
|
92
|
+
}
|
93
|
+
});
|
94
|
+
}
|
95
|
+
|
96
|
+
function checkTSTypeAnnotationForPotentialIssue(node) {
|
97
|
+
const annotation = node.typeAnnotation;
|
98
|
+
if (annotation.type === 'TSUnionType') {
|
99
|
+
// matches foo(): X|Y
|
100
|
+
checkUnionReturnTypeForLit(annotation);
|
101
|
+
} else if (annotation.type === 'TSTypeReference') {
|
102
|
+
// matches many things, including foo(): Promise<X|Y>, which we do want
|
103
|
+
// to check.
|
104
|
+
|
105
|
+
if (annotation.typeName.name !== 'Promise') {
|
106
|
+
// If it's not a promise, bail out.
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
// Represents the generic type passed to the promise: if our code is
|
110
|
+
// Promise<X>, this node represents the X.
|
111
|
+
const promiseGenericNode = annotation.typeParameters.params[0];
|
112
|
+
if (promiseGenericNode && promiseGenericNode.type === 'TSUnionType') {
|
113
|
+
checkUnionReturnTypeForLit(promiseGenericNode);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
function checkFunctionDeclarationOrExpressionForUnionType(node) {
|
119
|
+
if (node.returnType.type !== 'TSTypeAnnotation') {
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
checkTSTypeAnnotationForPotentialIssue(node.returnType);
|
123
|
+
}
|
124
|
+
|
125
|
+
return {
|
126
|
+
// function() {}
|
127
|
+
FunctionDeclaration(node) {
|
128
|
+
checkFunctionDeclarationOrExpressionForUnionType(node);
|
129
|
+
},
|
130
|
+
// Match functions defined inside classes
|
131
|
+
FunctionExpression(node) {
|
132
|
+
checkFunctionDeclarationOrExpressionForUnionType(node);
|
133
|
+
},
|
134
|
+
// Match values in interfaces or types.
|
135
|
+
TSPropertySignature(node) {
|
136
|
+
checkTSTypeAnnotationForPotentialIssue(node.typeAnnotation);
|
137
|
+
},
|
138
|
+
};
|
139
|
+
}
|
140
|
+
};
|
@@ -17,6 +17,10 @@ module.exports = {
|
|
17
17
|
create: function(context) {
|
18
18
|
function checkForOnlyInTestCases(testCaseObjects) {
|
19
19
|
for (const testCase of testCaseObjects) {
|
20
|
+
if (!testCase || !testCase.properties) {
|
21
|
+
continue;
|
22
|
+
}
|
23
|
+
|
20
24
|
const onlyKeyProp = testCase.properties.find(prop => {
|
21
25
|
return prop.key.name === 'only';
|
22
26
|
});
|
@@ -37,7 +41,7 @@ module.exports = {
|
|
37
41
|
// second argument = rule itself
|
38
42
|
// third argument = the object containing the test cases - what we want!
|
39
43
|
const tests = node.arguments[2];
|
40
|
-
if (!tests) {
|
44
|
+
if (!tests || !tests.properties) {
|
41
45
|
return;
|
42
46
|
}
|
43
47
|
|
@@ -0,0 +1,133 @@
|
|
1
|
+
// Copyright 2020 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
'use strict';
|
5
|
+
|
6
|
+
const rule = require('../lib/lit_template_result_or_nothing.js');
|
7
|
+
const ruleTester = new (require('eslint').RuleTester)({
|
8
|
+
parserOptions: {ecmaVersion: 9, sourceType: 'module'},
|
9
|
+
parser: require.resolve('@typescript-eslint/parser'),
|
10
|
+
});
|
11
|
+
|
12
|
+
ruleTester.run('lit_template_result_or_nothing', rule, {
|
13
|
+
valid: [
|
14
|
+
{
|
15
|
+
code: 'function foo(): LitHtml.LitTemplate {}',
|
16
|
+
filename: 'front_end/components/datagrid.ts',
|
17
|
+
},
|
18
|
+
{
|
19
|
+
code: 'function foo(): Promise<LitHtml.LitTemplate> {}',
|
20
|
+
filename: 'front_end/components/datagrid.ts',
|
21
|
+
},
|
22
|
+
{
|
23
|
+
code: 'function foo(): Promise<LitHtml.LitTemplate|SomeOtherType> {}',
|
24
|
+
filename: 'front_end/components/datagrid.ts',
|
25
|
+
},
|
26
|
+
{
|
27
|
+
code: 'function foo(): LitHtml.LitTemplate|string {}',
|
28
|
+
filename: 'front_end/components/datagrid.ts',
|
29
|
+
},
|
30
|
+
{
|
31
|
+
code: 'function foo(): LitHtml.TemplateResult|string {}',
|
32
|
+
filename: 'front_end/components/datagrid.ts',
|
33
|
+
},
|
34
|
+
],
|
35
|
+
invalid: [
|
36
|
+
{
|
37
|
+
code: 'function foo(): LitHtml.TemplateResult|{} {}',
|
38
|
+
filename: 'front_end/components/datagrid.ts',
|
39
|
+
errors: [{messageId: 'useLitTemplateOverEmptyObject'}],
|
40
|
+
output: 'function foo(): LitHtml.LitTemplate {}',
|
41
|
+
},
|
42
|
+
{
|
43
|
+
code: 'function foo(): LitHtml.TemplateResult|{}|number {}',
|
44
|
+
filename: 'front_end/components/datagrid.ts',
|
45
|
+
errors: [{messageId: 'useLitTemplateOverEmptyObject'}],
|
46
|
+
output: 'function foo(): LitHtml.LitTemplate|number {}',
|
47
|
+
},
|
48
|
+
{
|
49
|
+
code: 'function foo(): LitHtml.TemplateResult|typeof LitHtml.nothing {}',
|
50
|
+
filename: 'front_end/components/datagrid.ts',
|
51
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
52
|
+
output: 'function foo(): LitHtml.LitTemplate {}',
|
53
|
+
},
|
54
|
+
{
|
55
|
+
code: 'function foo(): LitHtml.TemplateResult|typeof LitHtml.nothing|number {}',
|
56
|
+
filename: 'front_end/components/datagrid.ts',
|
57
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
58
|
+
output: 'function foo(): LitHtml.LitTemplate|number {}',
|
59
|
+
},
|
60
|
+
{
|
61
|
+
code: 'function foo(): typeof LitHtml.nothing|LitHtml.TemplateResult {}',
|
62
|
+
filename: 'front_end/components/datagrid.ts',
|
63
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
64
|
+
output: 'function foo(): LitHtml.LitTemplate {}',
|
65
|
+
},
|
66
|
+
{
|
67
|
+
code: `class Bar {
|
68
|
+
foo(): typeof LitHtml.nothing|LitHtml.TemplateResult {}
|
69
|
+
}`,
|
70
|
+
filename: 'front_end/components/datagrid.ts',
|
71
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
72
|
+
output: `class Bar {
|
73
|
+
foo(): LitHtml.LitTemplate {}
|
74
|
+
}`,
|
75
|
+
},
|
76
|
+
{
|
77
|
+
code: `class Bar {
|
78
|
+
#foo(): typeof LitHtml.nothing|LitHtml.TemplateResult {}
|
79
|
+
}`,
|
80
|
+
filename: 'front_end/components/datagrid.ts',
|
81
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
82
|
+
output: `class Bar {
|
83
|
+
#foo(): LitHtml.LitTemplate {}
|
84
|
+
}`,
|
85
|
+
},
|
86
|
+
{
|
87
|
+
code: `class Bar {
|
88
|
+
#foo(): LitHtml.TemplateResult|{} {}
|
89
|
+
}`,
|
90
|
+
filename: 'front_end/components/datagrid.ts',
|
91
|
+
errors: [{messageId: 'useLitTemplateOverEmptyObject'}],
|
92
|
+
output: `class Bar {
|
93
|
+
#foo(): LitHtml.LitTemplate {}
|
94
|
+
}`,
|
95
|
+
},
|
96
|
+
{
|
97
|
+
code: 'function foo(): Promise<LitHtml.TemplateResult|{}> {}',
|
98
|
+
filename: 'front_end/components/datagrid.ts',
|
99
|
+
errors: [{messageId: 'useLitTemplateOverEmptyObject'}],
|
100
|
+
output: 'function foo(): Promise<LitHtml.LitTemplate> {}',
|
101
|
+
},
|
102
|
+
{
|
103
|
+
code: `interface Foo {
|
104
|
+
someThing: LitHtml.TemplateResult|typeof LitHtml.nothing;
|
105
|
+
}`,
|
106
|
+
filename: 'front_end/components/datagrid.ts',
|
107
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
108
|
+
output: `interface Foo {
|
109
|
+
someThing: LitHtml.LitTemplate;
|
110
|
+
}`,
|
111
|
+
},
|
112
|
+
{
|
113
|
+
code: `interface Foo {
|
114
|
+
someThing: Promise<LitHtml.TemplateResult|{}>;
|
115
|
+
}`,
|
116
|
+
filename: 'front_end/components/datagrid.ts',
|
117
|
+
errors: [{messageId: 'useLitTemplateOverEmptyObject'}],
|
118
|
+
output: `interface Foo {
|
119
|
+
someThing: Promise<LitHtml.LitTemplate>;
|
120
|
+
}`,
|
121
|
+
},
|
122
|
+
{
|
123
|
+
code: `type Foo = {
|
124
|
+
someThing: LitHtml.TemplateResult|typeof LitHtml.nothing;
|
125
|
+
}`,
|
126
|
+
filename: 'front_end/components/datagrid.ts',
|
127
|
+
errors: [{messageId: 'useLitTemplateOverTypeOfNothing'}],
|
128
|
+
output: `type Foo = {
|
129
|
+
someThing: LitHtml.LitTemplate;
|
130
|
+
}`,
|
131
|
+
},
|
132
|
+
]
|
133
|
+
});
|
@@ -55,7 +55,7 @@ server.once('listening', () => {
|
|
55
55
|
}
|
56
56
|
console.log(`Started hosted mode server at http://localhost:${actualPort}\n`);
|
57
57
|
console.log('For info on using the hosted mode server, see our contributing docs:');
|
58
|
-
console.log('https://
|
58
|
+
console.log('https://goo.gle/devtools-contribution-guide');
|
59
59
|
console.log('Tip: Look for the \'Development server options\' section\n');
|
60
60
|
});
|
61
61
|
const wss = new WebSocketServer({server});
|