Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Provide Spelling Suggestions for Unicode Property Value Expressions
  • Loading branch information
graphemecluster committed Sep 1, 2023
commit 1a5228d20452db775930201826fe8b46409a1097
2 changes: 1 addition & 1 deletion src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2322,7 +2322,7 @@ export function compareBooleans(a: boolean, b: boolean): Comparison {
*
* @internal
*/
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
export function getSpellingSuggestion<T>(name: string, candidates: Iterable<T>, getName: (candidate: T) => string | undefined): T | undefined {
const maximumLengthDifference = Math.max(2, Math.floor(name.length * 0.34));
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result is worse than this, don't bother.
let bestCandidate: T | undefined;
Expand Down
10 changes: 8 additions & 2 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
DeleteExpression,
Diagnostic,
DiagnosticArguments,
DiagnosticCategory,
DiagnosticMessage,
Diagnostics,
DiagnosticWithDetachedLocation,
Expand Down Expand Up @@ -115,6 +116,7 @@ import {
HasModifiers,
HeritageClause,
Identifier,
identity,
idText,
IfStatement,
ImportClause,
Expand Down Expand Up @@ -2114,7 +2116,11 @@ namespace Parser {
// Don't report another error if it would just be at the same position as the last error.
const lastError = lastOrUndefined(parseDiagnostics);
let result: DiagnosticWithDetachedLocation | undefined;
if (!lastError || start !== lastError.start) {
if (message.category === DiagnosticCategory.Message && lastError && start === lastError.start && length === lastError.length) {
Comment thread
rbuckton marked this conversation as resolved.
result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args);
addRelatedInfo(lastError, result);
}
else if (!lastError || start !== lastError.start) {
result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args);
parseDiagnostics.push(result);
}
Expand Down Expand Up @@ -2370,7 +2376,7 @@ namespace Parser {
}

// The user alternatively might have misspelled or forgotten to add a space after a common keyword.
const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, n => n) ?? getSpaceSuggestion(expressionText);
const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, identity) ?? getSpaceSuggestion(expressionText);
Comment thread
rbuckton marked this conversation as resolved.
if (suggestion) {
parseErrorAt(pos, node.end, Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion);
return;
Expand Down
13 changes: 13 additions & 0 deletions src/compiler/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
DiagnosticMessage,
Diagnostics,
forEach,
getSpellingSuggestion,
identity,
JSDocSyntaxKind,
JsxTokenSyntaxKind,
Expand Down Expand Up @@ -3302,6 +3303,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
else if (propertyName === undefined) {
error(Diagnostics.Unknown_Unicode_property_name, propertyNameOrValueStart, pos - propertyNameOrValueStart);
const suggestion = getSpellingSuggestion(propertyNameOrValue, nonBinaryUnicodeProperties.keys(), identity);
if (suggestion) {
error(Diagnostics.Did_you_mean_0, propertyNameOrValueStart, pos - propertyNameOrValueStart, suggestion);
}
}
pos++;
const propertyValueStart = pos;
Expand All @@ -3311,6 +3316,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
else if (propertyName !== undefined && !valuesOfNonBinaryUnicodeProperties[propertyName].has(propertyValue)) {
error(Diagnostics.Unknown_Unicode_property_value, propertyValueStart, pos - propertyValueStart);
const suggestion = getSpellingSuggestion(propertyValue, valuesOfNonBinaryUnicodeProperties[propertyName], identity);
if (suggestion) {
error(Diagnostics.Did_you_mean_0, propertyValueStart, pos - propertyValueStart, suggestion);
}
}
}
else {
Expand All @@ -3330,6 +3339,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
else if (!valuesOfNonBinaryUnicodeProperties.General_Category.has(propertyNameOrValue) && !binaryUnicodeProperties.has(propertyNameOrValue)) {
error(Diagnostics.Unknown_Unicode_property_name_or_value, propertyNameOrValueStart, pos - propertyNameOrValueStart);
const suggestion = getSpellingSuggestion(propertyNameOrValue, [...valuesOfNonBinaryUnicodeProperties.General_Category, ...binaryUnicodeProperties, ...binaryUnicodePropertiesOfStrings], identity);
if (suggestion) {
error(Diagnostics.Did_you_mean_0, propertyNameOrValueStart, pos - propertyNameOrValueStart, suggestion);
}
}
}
scanExpectedChar(CharacterCodes.closeBrace);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
regularExpressionUnicodePropertyValueExpressionSuggestions.ts(1,19): error TS1527: Unknown Unicode property name or value.
regularExpressionUnicodePropertyValueExpressionSuggestions.ts(1,28): error TS1522: Unknown Unicode property name.
regularExpressionUnicodePropertyValueExpressionSuggestions.ts(1,45): error TS1524: Unknown Unicode property value.
regularExpressionUnicodePropertyValueExpressionSuggestions.ts(1,55): error TS1499: This regular expression flag is only available when targeting 'ES2015' or later.


==== regularExpressionUnicodePropertyValueExpressionSuggestions.ts (4 errors) ====
const regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;
~~~~~
!!! error TS1527: Unknown Unicode property name or value.
!!! related TS1369 regularExpressionUnicodePropertyValueExpressionSuggestions.ts:1:19: Did you mean 'ASCII'?
~~
!!! error TS1522: Unknown Unicode property name.
!!! related TS1369 regularExpressionUnicodePropertyValueExpressionSuggestions.ts:1:28: Did you mean 'sc'?
~~~~~~~~
!!! error TS1524: Unknown Unicode property value.
!!! related TS1369 regularExpressionUnicodePropertyValueExpressionSuggestions.ts:1:45: Did you mean 'Unknown'?
~
!!! error TS1499: This regular expression flag is only available when targeting 'ES2015' or later.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/regularExpressionUnicodePropertyValueExpressionSuggestions.ts] ////

//// [regularExpressionUnicodePropertyValueExpressionSuggestions.ts]
const regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;


//// [regularExpressionUnicodePropertyValueExpressionSuggestions.js]
var regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//// [tests/cases/compiler/regularExpressionUnicodePropertyValueExpressionSuggestions.ts] ////

=== regularExpressionUnicodePropertyValueExpressionSuggestions.ts ===
const regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;
>regex : Symbol(regex, Decl(regularExpressionUnicodePropertyValueExpressionSuggestions.ts, 0, 5))

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//// [tests/cases/compiler/regularExpressionUnicodePropertyValueExpressionSuggestions.ts] ////

=== regularExpressionUnicodePropertyValueExpressionSuggestions.ts ===
const regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;
>regex : RegExp
>/\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u : RegExp

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const regex = /\p{ascii}\p{Sc=Unknown}\p{sc=unknownX}/u;