From e85bec00a2e1fa7b1a31c5d916801886dda62823 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 6 May 2017 22:52:37 -0400 Subject: [PATCH] add a few type annotations --- src/generators/Generator.ts | 6 ++- src/generators/dom/Block.ts | 8 ++-- src/generators/shared/utils/getIntro.ts | 4 +- src/generators/shared/utils/getOutro.ts | 2 +- src/parse/read/directives.ts | 8 ++-- src/parse/read/script.ts | 2 +- src/parse/read/style.ts | 2 +- src/parse/utils/hash.ts | 2 +- src/parse/utils/html.ts | 4 +- src/shared/_build.js | 2 +- src/utils/CodeBuilder.ts | 49 ++++++++++++++----------- src/utils/getCodeFrame.ts | 4 +- src/utils/isReference.ts | 2 +- src/utils/isVoidElementName.ts | 2 +- src/utils/toSource.ts | 4 +- src/utils/trim.ts | 4 +- tsconfig.json | 4 +- 17 files changed, 61 insertions(+), 48 deletions(-) diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index 413c966521..18135a3045 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -14,7 +14,11 @@ import annotateWithScopes from '../utils/annotateWithScopes'; const test = typeof global !== 'undefined' && global.__svelte_test; export default class Generator { - constructor ( parsed, source, name, options ) { + source: string + name: string + // TODO all the rest... + + constructor ( parsed, source: string, name: string, options ) { this.parsed = parsed; this.source = source; this.name = name; diff --git a/src/generators/dom/Block.ts b/src/generators/dom/Block.ts index 0d56584986..b471b7f00f 100644 --- a/src/generators/dom/Block.ts +++ b/src/generators/dom/Block.ts @@ -55,7 +55,7 @@ export default class Block { }); } - addElement ( name, renderStatement, parentNode, needsIdentifier = false ) { + addElement ( name: string, renderStatement: string, parentNode, needsIdentifier = false ) { const isToplevel = !parentNode; if ( needsIdentifier || isToplevel ) { this.builders.create.addLine( @@ -72,7 +72,7 @@ export default class Block { } } - addVariable ( name, init ) { + addVariable ( name: string, init ) { if ( this.variables.has( name ) && this.variables.get( name ) !== init ) { throw new Error( `Variable '${name}' already initialised with a different value` ); } @@ -80,7 +80,7 @@ export default class Block { this.variables.set( name, init ); } - alias ( name ) { + alias ( name: string ) { if ( !this.aliases.has( name ) ) { this.aliases.set( name, this.getUniqueName( name ) ); } @@ -100,7 +100,7 @@ export default class Block { return this.generator.findDependencies( this.contextDependencies, this.indexes, expression ); } - mount ( name, parentNode ) { + mount ( name: string, parentNode: string ) { if ( parentNode ) { this.builders.create.addLine( `${this.generator.helper( 'appendNode' )}( ${name}, ${parentNode} );` ); } else { diff --git a/src/generators/shared/utils/getIntro.ts b/src/generators/shared/utils/getIntro.ts index 56bb7c4c82..6b9bf97815 100644 --- a/src/generators/shared/utils/getIntro.ts +++ b/src/generators/shared/utils/getIntro.ts @@ -1,7 +1,7 @@ import deindent from '../../../utils/deindent.js'; import getGlobals from './getGlobals'; -export default function getIntro ( format, options, imports ) { +export default function getIntro ( format: string, options, imports ) { if ( format === 'es' ) return ''; if ( format === 'amd' ) return getAmdIntro( options, imports ); if ( format === 'cjs' ) return getCjsIntro( options, imports ); @@ -69,7 +69,7 @@ function paramString ( imports ) { return imports.length ? ` ${imports.map( dep => dep.name ).join( ', ' )} ` : ''; } -function removeExtension ( file ) { +function removeExtension ( file: string ) { const index = file.lastIndexOf( '.' ); return ~index ? file.slice( 0, index ) : file; } diff --git a/src/generators/shared/utils/getOutro.ts b/src/generators/shared/utils/getOutro.ts index a725727a45..b1cac890a3 100644 --- a/src/generators/shared/utils/getOutro.ts +++ b/src/generators/shared/utils/getOutro.ts @@ -1,6 +1,6 @@ import getGlobals from './getGlobals'; -export default function getOutro ( format, name, options, imports ) { +export default function getOutro ( format: string, name: string, options, imports ) { if ( format === 'es' ) { return `export default ${name};`; } diff --git a/src/parse/read/directives.ts b/src/parse/read/directives.ts index 32e86a0a4d..b0ac170a45 100644 --- a/src/parse/read/directives.ts +++ b/src/parse/read/directives.ts @@ -1,7 +1,7 @@ import { parseExpressionAt } from 'acorn'; import spaces from '../../utils/spaces.js'; -function readExpression ( parser, start, quoteMark ) { +function readExpression ( parser, start: number, quoteMark ) { let str = ''; let escaped = false; @@ -43,7 +43,7 @@ function readExpression ( parser, start, quoteMark ) { return expression; } -export function readEventHandlerDirective ( parser, start, name ) { +export function readEventHandlerDirective ( parser, start: number, name: string ) { const quoteMark = ( parser.eat( `'` ) ? `'` : parser.eat( `"` ) ? `"` : @@ -67,7 +67,7 @@ export function readEventHandlerDirective ( parser, start, name ) { }; } -export function readBindingDirective ( parser, start, name ) { +export function readBindingDirective ( parser, start: number, name: string ) { let value; if ( parser.eat( '=' ) ) { @@ -130,7 +130,7 @@ export function readBindingDirective ( parser, start, name ) { }; } -export function readTransitionDirective ( parser, start, name, type ) { +export function readTransitionDirective ( parser, start: number, name: string, type: string ) { let expression = null; if ( parser.eat( '=' ) ) { diff --git a/src/parse/read/script.ts b/src/parse/read/script.ts index 2d1156ad7d..45b0ee46f4 100644 --- a/src/parse/read/script.ts +++ b/src/parse/read/script.ts @@ -3,7 +3,7 @@ import spaces from '../../utils/spaces.js'; const scriptClosingTag = '<\/script>'; -export default function readScript ( parser, start, attributes ) { +export default function readScript ( parser, start: number, attributes ) { const scriptStart = parser.index; const scriptEnd = parser.template.indexOf( scriptClosingTag, scriptStart ); diff --git a/src/parse/read/style.ts b/src/parse/read/style.ts index d367aba627..03db000716 100644 --- a/src/parse/read/style.ts +++ b/src/parse/read/style.ts @@ -1,7 +1,7 @@ import parse from 'css-tree/lib/parser/index.js'; import walk from 'css-tree/lib/utils/walk.js'; -export default function readStyle ( parser, start, attributes ) { +export default function readStyle ( parser, start: number, attributes ) { const contentStart = parser.index; const styles = parser.readUntil( /<\/style>/ ); const contentEnd = parser.index; diff --git a/src/parse/utils/hash.ts b/src/parse/utils/hash.ts index 02dc221523..69f705c28f 100644 --- a/src/parse/utils/hash.ts +++ b/src/parse/utils/hash.ts @@ -1,5 +1,5 @@ // https://github.com/darkskyapp/string-hash/blob/master/index.js -export default function hash ( str ) { +export default function hash ( str: string ) { let hash = 5381; let i = str.length; diff --git a/src/parse/utils/html.ts b/src/parse/utils/html.ts index f4fdedf31c..4b06db0723 100644 --- a/src/parse/utils/html.ts +++ b/src/parse/utils/html.ts @@ -3,7 +3,7 @@ import htmlEntities from './entities'; const windows1252 = [ 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376 ]; const entityPattern = new RegExp( `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys( htmlEntities ).join( '|' )}));?`, 'g' ); -export function decodeCharacterReferences ( html ) { +export function decodeCharacterReferences ( html: string ) { return html.replace( entityPattern, ( match, entity ) => { let code; @@ -31,7 +31,7 @@ const NUL = 0; // to replace them ourselves // // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters -function validateCode ( code ) { +function validateCode ( code: number ) { // line feed becomes generic whitespace if ( code === 10 ) { return 32; diff --git a/src/shared/_build.js b/src/shared/_build.js index d608fb7820..3d8f1f3ae6 100644 --- a/src/shared/_build.js +++ b/src/shared/_build.js @@ -31,5 +31,5 @@ fs.readdirSync( __dirname ).forEach( file => { }); }); -fs.writeFileSync( 'src/generators/dom/shared.js', `// this file is auto-generated, do not edit it +fs.writeFileSync( 'src/generators/dom/shared.ts', `// this file is auto-generated, do not edit it export default ${JSON.stringify( declarations, null, '\t' )};` ); \ No newline at end of file diff --git a/src/utils/CodeBuilder.ts b/src/utils/CodeBuilder.ts index ff898776a0..79c36a96c6 100644 --- a/src/utils/CodeBuilder.ts +++ b/src/utils/CodeBuilder.ts @@ -1,18 +1,25 @@ -const LINE = {}; -const BLOCK = {}; +enum ChunkType { + Line, + Block +} export default class CodeBuilder { + result: string + first: ChunkType + last: ChunkType + lastCondition: string + constructor ( str = '' ) { this.result = str; - const initial = str ? ( /\n/.test( str ) ? BLOCK : LINE ) : null; + const initial = str ? ( /\n/.test( str ) ? ChunkType.Block : ChunkType.Line ) : null; this.first = initial; this.last = initial; this.lastCondition = null; } - addConditionalLine ( condition, line ) { + addConditionalLine ( condition: string, line: string ) { if ( condition === this.lastCondition ) { this.result += `\n\t${line}`; } else { @@ -24,41 +31,41 @@ export default class CodeBuilder { this.lastCondition = condition; } - this.last = BLOCK; + this.last = ChunkType.Block; } - addLine ( line ) { + addLine ( line: string ) { if ( this.lastCondition ) { this.result += `\n}`; this.lastCondition = null; } - if ( this.last === BLOCK ) { + if ( this.last === ChunkType.Block ) { this.result += `\n\n${line}`; - } else if ( this.last === LINE ) { + } else if ( this.last === ChunkType.Line ) { this.result += `\n${line}`; } else { this.result += line; } - this.last = LINE; - if ( !this.first ) this.first = LINE; + this.last = ChunkType.Line; + if ( !this.first ) this.first = ChunkType.Line; } - addLineAtStart ( line ) { - if ( this.first === BLOCK ) { + addLineAtStart ( line: string ) { + if ( this.first === ChunkType.Block ) { this.result = `${line}\n\n${this.result}`; - } else if ( this.first === LINE ) { + } else if ( this.first === ChunkType.Line ) { this.result = `${line}\n${this.result}`; } else { this.result += line; } - this.first = LINE; - if ( !this.last ) this.last = LINE; + this.first = ChunkType.Line; + if ( !this.last ) this.last = ChunkType.Line; } - addBlock ( block ) { + addBlock ( block: string ) { if ( this.lastCondition ) { this.result += `\n}`; this.lastCondition = null; @@ -70,19 +77,19 @@ export default class CodeBuilder { this.result += block; } - this.last = BLOCK; - if ( !this.first ) this.first = BLOCK; + this.last = ChunkType.Block; + if ( !this.first ) this.first = ChunkType.Block; } - addBlockAtStart ( block ) { + addBlockAtStart ( block: string ) { if ( this.result ) { this.result = `${block}\n\n${this.result}`; } else { this.result += block; } - this.first = BLOCK; - if ( !this.last ) this.last = BLOCK; + this.first = ChunkType.Block; + if ( !this.last ) this.last = ChunkType.Block; } isEmpty () { diff --git a/src/utils/getCodeFrame.ts b/src/utils/getCodeFrame.ts index 90fd01e98e..b87e267ff2 100644 --- a/src/utils/getCodeFrame.ts +++ b/src/utils/getCodeFrame.ts @@ -1,10 +1,10 @@ import spaces from './spaces.js'; -function tabsToSpaces ( str ) { +function tabsToSpaces ( str: string ) { return str.replace( /^\t+/, match => match.split( '\t' ).join( ' ' ) ); } -export default function getCodeFrame ( source, line, column ) { +export default function getCodeFrame ( source: string, line: number, column: number ) { const lines = source.split( '\n' ); const frameStart = Math.max( 0, line - 2 ); diff --git a/src/utils/isReference.ts b/src/utils/isReference.ts index c2e6c8967a..05d216f9ad 100644 --- a/src/utils/isReference.ts +++ b/src/utils/isReference.ts @@ -1,4 +1,4 @@ -export default function isReference ( node, parent ) { +export default function isReference ( node, parent ): boolean { if ( node.type === 'MemberExpression' ) { return !node.computed && isReference( node.object, node ); } diff --git a/src/utils/isVoidElementName.ts b/src/utils/isVoidElementName.ts index 8af4f34db8..b640cafbe8 100644 --- a/src/utils/isVoidElementName.ts +++ b/src/utils/isVoidElementName.ts @@ -1,5 +1,5 @@ const voidElementNames = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/; -export default function isVoidElementName ( name ) { +export default function isVoidElementName ( name: string ) { return voidElementNames.test( name ) || name.toLowerCase() === '!doctype'; } diff --git a/src/utils/toSource.ts b/src/utils/toSource.ts index 8809cb15ff..2318a6bd44 100644 --- a/src/utils/toSource.ts +++ b/src/utils/toSource.ts @@ -1,6 +1,6 @@ import deindent from './deindent.js'; -export default function toSource ( thing ) { +export default function toSource ( thing: any ) :string { if ( typeof thing === 'function' ) { return normaliseIndentation( thing.toString() ); } @@ -25,7 +25,7 @@ export default function toSource ( thing ) { return JSON.stringify( thing ); } -function normaliseIndentation ( str ) { +function normaliseIndentation ( str: string ) { const lines = str.split( '\n' ).slice( 1, -1 ); let minIndentation = Infinity; diff --git a/src/utils/trim.ts b/src/utils/trim.ts index f9403877eb..3c339a159b 100644 --- a/src/utils/trim.ts +++ b/src/utils/trim.ts @@ -1,13 +1,13 @@ import { whitespace } from './patterns'; -export function trimStart ( str ) { +export function trimStart ( str: string ) { let i = 0; while ( whitespace.test( str[i] ) ) i += 1; return str.slice( i ); } -export function trimEnd ( str ) { +export function trimEnd ( str: string ) { let i = str.length; while ( whitespace.test( str[ i - 1 ] ) ) i -= 1; diff --git a/tsconfig.json b/tsconfig.json index 571a841725..080fbe6644 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,9 @@ "noImplicitAny": true, "diagnostics": true, "noImplicitThis": true, - "noEmitOnError": true + "noEmitOnError": true, + "allowJs": true, + "lib": ["es5", "es6", "dom"] }, "target": "ES5", "include": [