diff --git a/.eslintrc.js b/.eslintrc.js index 42d46dd07..2967f1cd9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,10 @@ module.exports = { // project-specific settings curly: [2, 'all'], 'max-len': 'off', // handled by prettier + 'no-restricted-properties': [ + 'error', + { property: 'substr', message: 'Use .slice instead of .substr.' }, + ], 'no-trailing-spaces': 'error', 'one-var': ['error', 'never'], '@typescript-eslint/no-unused-vars': ['error', { args: 'none' }], diff --git a/packages/language-server/src/plugins/svelte/features/getCompletions.ts b/packages/language-server/src/plugins/svelte/features/getCompletions.ts index 606b36c0f..7356ab0d0 100644 --- a/packages/language-server/src/plugins/svelte/features/getCompletions.ts +++ b/packages/language-server/src/plugins/svelte/features/getCompletions.ts @@ -43,7 +43,7 @@ export function getCompletions( const lastCharactersBeforePosition = svelteDoc .getText() // use last 10 characters, should cover 99% of all cases - .substr(Math.max(offset - 10, 0), Math.min(offset, 10)); + .slice(Math.max(offset - 10, 0), Math.max(offset - 10, 0) + 10); const precededByOpeningBracket = /[\s\S]*{\s*[#:/@]\w*$/.test(lastCharactersBeforePosition); if (isInStyleOrScript) { return null; diff --git a/packages/language-server/src/plugins/svelte/features/getHoverInfo.ts b/packages/language-server/src/plugins/svelte/features/getHoverInfo.ts index 4bd1a69e1..f59e5c52b 100644 --- a/packages/language-server/src/plugins/svelte/features/getHoverInfo.ts +++ b/packages/language-server/src/plugins/svelte/features/getHoverInfo.ts @@ -26,7 +26,7 @@ export function getHoverInfo( const charactersAroundOffset = svelteDoc .getText() // use last 10 and next 10 characters, should cover 99% of all cases - .substr(offsetStart, 20); + .slice(offsetStart, offsetStart + 20); const isSvelteTag = tagRegexp.test(charactersAroundOffset); if (isInStyleOrScript) { diff --git a/packages/language-server/src/plugins/typescript/features/HoverProvider.ts b/packages/language-server/src/plugins/typescript/features/HoverProvider.ts index cae5834a9..0c7759a0a 100644 --- a/packages/language-server/src/plugins/typescript/features/HoverProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/HoverProvider.ts @@ -75,7 +75,7 @@ export class HoverProviderImpl implements HoverProvider { return null; } - const eventName = possibleEventName.substr('on:'.length); + const eventName = possibleEventName.slice('on:'.length); const event = component.getEvents().find((event) => event.name === eventName); if (!event) { return null; diff --git a/packages/language-server/src/plugins/typescript/features/RenameProvider.ts b/packages/language-server/src/plugins/typescript/features/RenameProvider.ts index c81ae64bc..abe194e7c 100644 --- a/packages/language-server/src/plugins/typescript/features/RenameProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/RenameProvider.ts @@ -283,9 +283,9 @@ export class RenameProviderImpl implements RenameProvider { ) { const regex = new RegExp( // no 'export let', only 'let', because that's what it's translated to in svelte2tsx - `\\s+let\\s+(${fragment.text.substr( + `\\s+let\\s+(${fragment.text.slice( updatePropLocation.textSpan.start, - updatePropLocation.textSpan.length + updatePropLocation.textSpan.start + updatePropLocation.textSpan.length )})($|\\s|;|:)` ); const match = fragment.text.match(regex); @@ -480,7 +480,7 @@ export class RenameProviderImpl implements RenameProvider { const originalStart = offsetAt(location.range.start, originalText); const isShortHandBinding = - originalText.substr(originalStart - bind.length, bind.length) === bind; + originalText.slice(originalStart - bind.length, originalStart) === bind; const directiveName = (isShortHandBinding ? bind : '') + identifierName; const prefixText = directiveName + '={'; diff --git a/packages/language-server/src/plugins/typescript/previewer.ts b/packages/language-server/src/plugins/typescript/previewer.ts index 168b91abf..3d1891c7f 100644 --- a/packages/language-server/src/plugins/typescript/previewer.ts +++ b/packages/language-server/src/plugins/typescript/previewer.ts @@ -53,7 +53,7 @@ function getTagBodyText(tag: ts.JSDocTagInfo): string | undefined { return ( captionTagMatches[1] + '\n\n' + - makeCodeblock(text.substr(captionTagMatches[0].length)) + makeCodeblock(text.slice(captionTagMatches[0].length)) ); } else { return makeCodeblock(text); diff --git a/packages/language-server/src/plugins/typescript/utils.ts b/packages/language-server/src/plugins/typescript/utils.ts index e72ab7809..84400e54d 100644 --- a/packages/language-server/src/plugins/typescript/utils.ts +++ b/packages/language-server/src/plugins/typescript/utils.ts @@ -13,7 +13,7 @@ import { pathToUrl } from '../../utils'; import { SnapshotFragment, SvelteSnapshotFragment } from './DocumentSnapshot'; export function getScriptKindFromFileName(fileName: string): ts.ScriptKind { - const ext = fileName.substr(fileName.lastIndexOf('.')); + const ext = fileName.slice(fileName.lastIndexOf('.')); switch (ext.toLowerCase()) { case ts.Extension.Js: return ts.ScriptKind.JS; diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts index 68533b958..aabaa2dc0 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts @@ -208,7 +208,7 @@ function sanitizeLeadingChars(attrName: string): string { let sanitizedName = ''; for (let i = 0; i < attrName.length; i++) { if (/[A-Za-z$_]/.test(attrName[i])) { - sanitizedName += attrName.substr(i); + sanitizedName += attrName.slice(i); return sanitizedName; } else { sanitizedName += '_'; diff --git a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts index 1592e77cc..17e0a9c38 100644 --- a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts +++ b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts @@ -196,7 +196,7 @@ function classNameFromFilename(filename: string, appendSuffix: boolean): string // Although _ and $ are valid first characters for classes, they are invalid first characters // for tag names. For a better import autocompletion experience, we therefore throw them out. .findIndex((char) => /[A-Za-z]/.test(char)); - const withoutLeadingInvalidCharacters = withoutInvalidCharacters.substr(firstValidCharIdx); + const withoutLeadingInvalidCharacters = withoutInvalidCharacters.slice(firstValidCharIdx); const inPascalCase = pascalCase(withoutLeadingInvalidCharacters); const finalName = firstValidCharIdx === -1 ? `A${inPascalCase}` : inPascalCase; return `${finalName}${appendSuffix ? COMPONENT_SUFFIX : ''}`;