diff --git a/packages/ERTP/src/issuer.js b/packages/ERTP/src/issuer.js index 4a628fe0a10..42b73b811e3 100644 --- a/packages/ERTP/src/issuer.js +++ b/packages/ERTP/src/issuer.js @@ -1,9 +1,7 @@ // @ts-check +// @jessie-check /* global makeWeakStore */ -// Let's hold off on this until agoric-sdk/issues/2704 is addressed. -// 'use jessie'; - import { assert, details as X } from '@agoric/assert'; import { makeExternalStore } from '@agoric/store'; import { E } from '@agoric/eventual-send'; diff --git a/packages/eslint-plugin/lib/processors/use-jessie.js b/packages/eslint-plugin/lib/processors/use-jessie.js index 1ba5bcbba12..ab23580f9ee 100644 --- a/packages/eslint-plugin/lib/processors/use-jessie.js +++ b/packages/eslint-plugin/lib/processors/use-jessie.js @@ -1,5 +1,8 @@ 'use strict'; +const USE_JESSIE_BEFORE_FIRST_STATEMENT_REGEXP = /^\s*\/\/\s*@jessie-check\s*$/m; +const USE_JESSIE_FIRST_STATEMENT_REGEXP = /^('use\s+jessie'|"use\s+jessie"|import\s+('@jessie.js\/transform-this-module'|"jessie.js\/transform-this-module"))/; + // This is all one line so that we don't mess up // eslint's error locations. // @@ -9,80 +12,90 @@ const jessieRulesOneLine = `\ curly: ['error', 'all']\ ,eqeqeq: ['error', 'always']\ ,no-bitwise: ['error']\ -,no-fallthrough: ['error', { commentPattern: 'fallthrough is not allowed' }]\ -,no-plusplus: ['error']\ +,no-fallthrough: ['error', { commentPattern: 'fallthrough is not allowed in Jessie' }]\ ,no-restricted-globals: ['error', 'RegExp', 'Date']\ ,no-restricted-syntax: ['error', \ {\ selector: "BinaryExpression[operator='in']",\ - message: "'in' is not allowed.",\ + message: "'in' is not allowed in Jessie",\ +},\ +{\ + selector: "UpdateExpression[operator='++'][prefix=false]",\ + message: "postfix '++' is not allowed in Jessie",\ +},\ +{\ + selector: "UpdateExpression[operator='--'][prefix=false]",\ + message: "postfix '--' is not allowed in Jessie",\ },\ {\ selector: "BinaryExpression[operator='instanceof']",\ - message: "'instanceof' is not allowed.",\ + message: "'instanceof' is not allowed in Jessie",\ },\ {\ selector: 'NewExpression',\ - message: "'new' is not allowed.",\ + message: "'new' is not allowed in Jessie",\ },\ {\ selector: 'FunctionDeclaration[generator=true]',\ - message: 'generators are not allowed.',\ + message: 'generators are not allowed in Jessie',\ },\ {\ selector: 'FunctionDeclaration[async=true]',\ - message: 'async functions are not allowed.',\ + message: 'async functions are not allowed in Jessie',\ },\ {\ selector: 'FunctionExpression[async=true]',\ - message: 'async functions are not allowed.',\ + message: 'async functions are not allowed in Jessie',\ },\ {\ selector: 'ArrowFunctionExpression[async=true]',\ - message: 'async functions are not allowed.',\ + message: 'async functions are not allowed in Jessie',\ },\ {\ selector: 'DoWhileStatement',\ - message: 'do/while statements are not allowed.',\ + message: 'do/while statements are not allowed in Jessie',\ },\ {\ selector: 'ThisExpression',\ - message: "'this' not allowed.",\ + message: "'this' not allowed in Jessie",\ },\ {\ selector: "UnaryExpression[operator='delete']",\ - message: "'delete' not allowed.",\ + message: "'delete' not allowed in Jessie",\ },\ {\ selector: 'ForInStatement',\ - message: 'for/in statements are not allowed; use for/of Object.keys(val).',\ + message: 'for/in statements are not allowed in Jessie; use for/of Object.keys(val).',\ +},\ +{\ + selector: 'MemberExpression[computed=true][property.type!="Literal"][property.type!="UnaryExpression"]',\ + message: "computed property names are not allowed in Jessie (except with leading '+')",\ },\ {\ - selector: 'MemberExpression[computed=true]',\ - message: 'computed property names are not allowed.',\ + selector: 'MemberExpression[computed=true][property.type="UnaryExpression"][property.operator!="+"]',\ + message: 'computed property names are not allowed in Jessie (except with leading '+')',\ },\ {\ selector: 'Super',\ - message: "'super' is not allowed.",\ + message: "'super' is not allowed in Jessie",\ },\ {\ selector: 'MetaProperty',\ - message: "'MetaProperty' is not allowed.",\ + message: "'MetaProperty' is not allowed in Jessie",\ },\ {\ selector: 'ClassExpression',\ - message: "'ClassExpression' is not allowed.",\ + message: "'ClassExpression' is not allowed in Jessie",\ },\ {\ selector: "CallExpression[callee.name='eval']",\ - message: "'eval' is not allowed.",\ + message: "'eval' is not allowed in Jessie",\ },\ {\ selector: 'Literal[regex]',\ - message: 'regexp literal syntax is not allowed.',\ + message: 'regexp literal syntax is not allowed in Jessie',\ }\ ]\ -,no-ternary: ['error']\ ,no-var: ['error']\ ,guard-for-in: 'off'\ ,semi: ['error', 'always']\ @@ -130,36 +143,50 @@ function indexOfFirstStatement(text) { function isJessie(text) { const pos = indexOfFirstStatement(text); + if (text.substr(0, pos).match(USE_JESSIE_BEFORE_FIRST_STATEMENT_REGEXP)) { + return true; + } if (pos >= 0) { - for (const jessieToken of ['"use jessie";', "'use jessie';"]) { - if (text.substr(pos, jessieToken.length) === jessieToken) { - return true; - } + if (USE_JESSIE_FIRST_STATEMENT_REGEXP.test(text.substr(pos))) { + return true; } } return false; } -const filenameIsJessie = new Set(); +const prependedText = text => { + if (!isJessie(text)) { + return ''; + } + let prepend = jessieRulesOneLine; + if (text.startsWith('#!')) { + prepend += '// '; + } + return prepend; +} + +const filenameToPrepend = new Map(); module.exports = { preprocess(text, filename) { - if (isJessie(text)) { - filenameIsJessie.add(filename); + const prepend = prependedText(text); + if (prepend) { + filenameToPrepend.set(filename, prepend); return [ - `${jessieRulesOneLine}${text}` + `${prepend}${text}` ]; } - filenameIsJessie.delete(filename); + filenameToPrepend.delete(filename); return [text]; }, postprocess(messages, filename) { - if (!filenameIsJessie.has(filename)) { + if (!filenameToPrepend.has(filename)) { return [].concat(...messages); } + const prepend = filenameToPrepend.get(filename); const rewritten = messages.flatMap(errors => errors.map(err => { if ('fix' in err) { - // Remove the bytes we inserted. - const range = err.fix.range.map(offset => offset > jessieRulesOneLine.length ? offset - jessieRulesOneLine.length : offset); + // Remove the prepension we inserted. + const range = err.fix.range.map(offset => Math.max(offset - prepend.length, 0)); return { ...err, fix: { ...err.fix, range }}; } return err;