├── .gitignore ├── README.md ├── bin └── dts-parser ├── index.js ├── lib.d.ts.parsed ├── package.json ├── src ├── cli.coffee ├── nodes.coffee ├── parser.coffee └── typescript.coffee ├── test ├── fixtures │ ├── arrayable.d.ts │ ├── comments.d.ts │ ├── dot.d.ts │ ├── dummy.d.ts │ ├── exported_function.d.ts │ ├── extends.d.ts │ ├── function.d.ts │ ├── generics.d.ts │ ├── interface.d.ts │ ├── multi_module.d.ts │ ├── nested.d.ts │ └── nullable.d.ts ├── parse-test.coffee └── parsed │ ├── arrayable.d.ts.json │ ├── comments.d.ts.json │ ├── dot.d.ts.json │ ├── dummy.d.ts.json │ ├── exported_function.d.ts.json │ ├── extends.d.ts.json │ ├── function.d.ts.json │ ├── generics.d.ts.json │ ├── interface.d.ts.json │ ├── multi_module.d.ts.json │ ├── nested.d.ts.json │ └── nullable.d.ts.json └── update-fixtures /.gitignore: -------------------------------------------------------------------------------- 1 | typings 2 | tsd.json 3 | node_modules 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dts-parser 2 | 3 | [![Build Status](https://drone.io/github.com/mizchi/dts-parser/status.png)](https://drone.io/github.com/mizchi/dts-parser/latest) 4 | 5 | TypeScript d.ts parser. 6 | 7 | It generates AST like JSON. 8 | 9 | See output detail in `lib.d.ts.parsed`. 10 | 11 | ## Features 12 | 13 | - ✔ module 14 | - ✔ nested module 15 | - ✔ class 16 | - ✔ variable declaration 17 | - ✔ string/number/boolean/any/lambda 18 | - ✔ function 19 | - ✔ interface 20 | - ✔ generics in class 21 | - ✔ generics in interface 22 | - ✔ generics in function 23 | - ✔ T[] 24 | - ✔ nullable? 25 | - ✔ class - extends 26 | - ✔ class - implement 27 | - ✔ interface - extends 28 | 29 | ## Install 30 | 31 | ``` 32 | npm install dts-parser -g 33 | ``` 34 | 35 | ## Examples 36 | 37 | 38 | examples/dummy.d.ts 39 | 40 | ```typescript 41 | declare module Foo { 42 | export function fun(str?: number[]):void; 43 | export var a:number; 44 | export class Bar { 45 | x: any; 46 | } 47 | } 48 | 49 | export class X {} 50 | export var x: any; 51 | 52 | export interface IFoo { 53 | s: string; 54 | f: (t:number) => Object[]; 55 | } 56 | 57 | export interface IFoo2 extends IFOO { 58 | n : number; 59 | } 60 | 61 | ``` 62 | 63 | ``` 64 | $ npm install -g 65 | $ dts-parser examples/dummy.d.ts 66 | nodeType: TopModule 67 | moduleName: Top 68 | modules: 69 | - 70 | nodeType: Module 71 | moduleName: Foo 72 | modules: 73 | (empty array) 74 | classes: 75 | - 76 | nodeType: ClassNode 77 | className: Bar 78 | properties: 79 | - 80 | nodeType: VariableNode 81 | propertyName: x 82 | typeAnnotation: 83 | nodeType: AnnotatedType 84 | typeName: Any 85 | typeArguments: 86 | (empty array) 87 | isArray: false 88 | typeParameters: null 89 | heritages: 90 | implementList: null 91 | extend: null 92 | properties: 93 | - 94 | propertyName: fun 95 | typeAnnotation: 96 | nodeType: Function 97 | returnType: 98 | nodeType: AnnotatedType 99 | typeName: Void 100 | typeArguments: 101 | (empty array) 102 | isArray: false 103 | arguments: 104 | - 105 | nodeType: FunctionArgument 106 | identifierName: str 107 | typeAnnotation: 108 | nodeType: AnnotatedType 109 | typeArguments: 110 | (empty array) 111 | isArray: true 112 | nullable: true 113 | spriced: false 114 | typeParameters: null 115 | - 116 | nodeType: VariableDeclarationNode 117 | propertyName: a 118 | typeAnnotation: 119 | nodeType: AnnotatedType 120 | typeName: Number 121 | typeArguments: 122 | (empty array) 123 | isArray: false 124 | interfaces: 125 | (empty array) 126 | classes: 127 | - 128 | nodeType: ClassNode 129 | className: X 130 | properties: 131 | (empty array) 132 | typeParameters: null 133 | heritages: 134 | implementList: null 135 | extend: null 136 | properties: 137 | - 138 | nodeType: VariableDeclarationNode 139 | propertyName: x 140 | typeAnnotation: 141 | nodeType: AnnotatedType 142 | typeName: Any 143 | typeArguments: 144 | (empty array) 145 | isArray: false 146 | interfaces: 147 | - 148 | nodeType: InterfaceNode 149 | interfaceName: IFoo 150 | properties: 151 | - 152 | nodeType: VariableDeclarationNode 153 | propertyName: s 154 | typeAnnotation: 155 | nodeType: AnnotatedType 156 | typeName: String 157 | typeArguments: 158 | (empty array) 159 | isArray: false 160 | - 161 | nodeType: VariableDeclarationNode 162 | propertyName: f 163 | typeAnnotation: 164 | nodeType: LambdaFunctionAnnotation 165 | annotationType: lambdaFunctionType 166 | typeAnnotation: 167 | nodeType: AnnotatedType 168 | typeName: Object 169 | typeArguments: 170 | (empty array) 171 | isArray: true 172 | arguments: 173 | - 174 | nodeType: FunctionArgument 175 | identifierName: t 176 | typeAnnotation: 177 | nodeType: AnnotatedType 178 | typeName: Number 179 | typeArguments: 180 | (empty array) 181 | isArray: false 182 | nullable: false 183 | spriced: false 184 | typeParameters: null 185 | heritages: 186 | implementList: null 187 | extend: null 188 | - 189 | nodeType: InterfaceNode 190 | interfaceName: IFoo2 191 | properties: 192 | - 193 | nodeType: VariableDeclarationNode 194 | propertyName: n 195 | typeAnnotation: 196 | nodeType: AnnotatedType 197 | typeName: Number 198 | typeArguments: 199 | (empty array) 200 | isArray: false 201 | typeParameters: null 202 | heritages: 203 | implementList: null 204 | extend: 205 | nodeType: AnnotatedType 206 | typeName: IFOO 207 | typeArguments: 208 | (empty array) 209 | isArray: false 210 | ``` 211 | 212 | ## Command Line Interface 213 | 214 | ``` 215 | npm install -g 216 | ``` 217 | 218 | - `-j, --json`: output as json 219 | - `-c`: output with no-color 220 | 221 | ## Use as node module 222 | 223 | ``` 224 | $ npm install dts-parser 225 | ``` 226 | 227 | ```coffee 228 | parser = require 'dts-parser' 229 | console.log parser.parse('declare var x: number;') 230 | ``` 231 | 232 | ## Test 233 | 234 | ``` 235 | $ npm install 236 | $ ./update-fixtures 237 | $ npm test 238 | ``` 239 | 240 | `test/parsed` have generated json by `./update-fixtures` from `test/fixtures`. 241 | 242 | Tests compare pre-generated json to json generated by current parser. 243 | 244 | ## Motivations 245 | 246 | TypeScript's type definitions are known in its own and has [borisyankov/DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped "borisyankov/DefinitelyTyped") 247 | 248 | ## LICENSE 249 | 250 | The MIT License (MIT) 251 | 252 | Copyright (c) 2014 Koutaro Chikuba 253 | 254 | Permission is hereby granted, free of charge, to any person obtaining a copy 255 | of this software and associated documentation files (the "Software"), to deal 256 | in the Software without restriction, including without limitation the rights 257 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 258 | copies of the Software, and to permit persons to whom the Software is 259 | furnished to do so, subject to the following conditions: 260 | 261 | The above copyright notice and this permission notice shall be included in 262 | all copies or substantial portions of the Software. 263 | 264 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 265 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 266 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 267 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 268 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 269 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 270 | THE SOFTWARE. 271 | -------------------------------------------------------------------------------- /bin/dts-parser: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('coffee-script/register') 3 | require('../src/cli').show(process.argv[2]); 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | fs = require('fs'); 2 | Parser = require('./src/parser'); 3 | TopModule = require('./src/nodes').TopModule; 4 | 5 | exports.parseFile = function(fpath) { 6 | source = fs.readFileSync(fpath).toString(); 7 | parser = new Parser; 8 | ast = parser.parse(source); 9 | top = new TopModule(ast._sourceUnit); 10 | return top.toJSON(); 11 | } 12 | 13 | exports.parse = function(source) { 14 | parser = new Parser; 15 | ast = parser.parse(source); 16 | top = new TopModule(ast._sourceUnit); 17 | return top.toJSON(); 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dts-parser", 3 | "version": "0.1.2", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "JSONSelect": "0.4.0", 8 | "coffee-script": "^1.7.1", 9 | "optimist": "^0.6.1", 10 | "prettyjson": "^1.0.0", 11 | "typescript": "^1.0.1" 12 | }, 13 | "scripts": { 14 | "test": "node_modules/.bin/mocha --compilers coffee:coffee-script/register --reporter spec" 15 | }, 16 | "bin": { 17 | "dts-parser": "./bin/dts-parser" 18 | }, 19 | "author": "", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "mocha": "^1.19.0" 23 | }, 24 | "directories": { 25 | "test": "test/" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/cli.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | path = require 'path' 3 | pj = require 'prettyjson' 4 | p = (obj) -> console.log pj.render obj, noColor: true 5 | 6 | Parser = require './parser' 7 | {TopModule} = require './nodes' 8 | 9 | argv = require('optimist') 10 | .boolean('nc') 11 | .boolean('tsast') 12 | .alias('c', 'nc') 13 | .alias('o', 'out') 14 | .alias('w', 'write') 15 | .boolean('write') 16 | .boolean('json') 17 | .alias('j', 'json') 18 | .argv 19 | 20 | output = (source) -> 21 | if argv.json 22 | console.log JSON.stringify source 23 | else 24 | console.log pj.render source, noColor: argv.nc 25 | 26 | exports.show = -> 27 | source = fs.readFileSync(argv._[0]).toString() 28 | parser = new Parser 29 | ast = parser.parse(source) 30 | 31 | if argv.tsast 32 | output ast 33 | return 34 | 35 | top = new TopModule ast._sourceUnit 36 | 37 | if argv.write 38 | outpath = (path.join (argv.out ? ''), path.basename(argv._[0]))+'.json' 39 | fs.writeFileSync outpath, JSON.stringify(top.toJSON()) 40 | console.log argv._[0], '->',outpath 41 | else 42 | reports = top.toJSON() 43 | output reports 44 | -------------------------------------------------------------------------------- /src/nodes.coffee: -------------------------------------------------------------------------------- 1 | $ = require('JSONSelect').match 2 | pj = require 'prettyjson' 3 | p = (obj) -> console.log pj.render obj, noColor: true 4 | TypeScript = require './typescript' 5 | 6 | mapClass = (Class, arr) -> arr.map (i) -> new Class(i) 7 | 8 | listToJSON = (list) -> list.map (i) -> i.toJSON() 9 | 10 | tokenKindToTypeKeyword = (tokenKind) -> 11 | for key, val of TypeScript.SyntaxKind 12 | if val is tokenKind then return key 13 | '' 14 | 15 | tokenKindToTypeName = (tokenKind)-> 16 | keyword = tokenKindToTypeKeyword(tokenKind) 17 | switch keyword 18 | when 'StringKeyword' then 'String' 19 | when 'NumberKeyword' then 'Number' 20 | when 'BooleanKeyword' then 'Boolean' 21 | when 'AnyKeyword' then 'Any' 22 | when 'VoidKeyword' then 'Void' 23 | when 'IdentifierName' then 'Identifier' 24 | 25 | itemOrElements = (node) -> 26 | if node.item then [node.item] 27 | else if node.elements then node.elements 28 | else [] 29 | 30 | itemOrNodeOrTokens = (node) -> 31 | if node.item then [node.item] 32 | else if node.nodeOrTokens then node.nodeOrTokens 33 | else [] 34 | 35 | typeToTypeName = (type) -> 36 | type._fullText ? tokenKindToTypeName type.tokenKind 37 | 38 | isFunctionNode = (node) -> node.callSignature? 39 | 40 | exports.Node = Node = class Node 41 | constructor: (@ast) -> 42 | 43 | $: (query) -> $ query, @ast 44 | 45 | $first: (query) -> @$(query)[0] 46 | 47 | toJSON: -> throw 'Not implemented' 48 | 49 | walkSymbol = (root)-> 50 | if root.dotToken 51 | (new MemberAccess root).toJSON() 52 | else 53 | return root._fullText if root._fullText? 54 | tokenKindToTypeName (root.tokenKind ? root.name.tokenKind) 55 | 56 | class MemberAccess extends Node 57 | """ 58 | A.B.Point 59 | 60 | left: 61 | left: 62 | _fullText: A 63 | dotToken: ... 64 | right: 65 | _fullText: B 66 | dotToken: ... 67 | right: 68 | _fullText: Point 69 | """ 70 | constructor: (@ast) -> 71 | toJSON: -> 72 | left = walkSymbol @ast.left 73 | right = walkSymbol @ast.right 74 | { left, right, nodeType: 'MemberAccess' } 75 | 76 | class AnnotatedType extends Node 77 | ''' 78 | TemplateApplication 79 | 80 | name: 81 | _fullText: Array 82 | typeArgumentList: 83 | typeArguments: 84 | item: 85 | _fullText: T 86 | 87 | simple 88 | _fullText: Array 89 | tokenKind: 11 90 | ''' 91 | 92 | typeName: -> 93 | return walkSymbol @ast.type.name if @ast.type?.name? 94 | 95 | fullText = @$first(':root ._fullText') ? @$first(':root > .name > ._fullText') 96 | return fullText if fullText? 97 | tokenKindToTypeName (@$first(':root > .tokenKind') ? @$first(':root .name > .tokenKind')) 98 | 99 | constructor: (@ast) -> 100 | 101 | isArray: -> @ast.openBracketToken? and @ast.closeBracketToken? 102 | 103 | typeArguments: -> 104 | header = ":root > .typeArgumentList > .typeArguments" 105 | items = @$(header + '> .item') 106 | items = 107 | if items.length > 0 then items 108 | else 109 | items = @$first(header+'> .elements')?.filter (i) -> i.identifier? 110 | items ?= [] 111 | 112 | items.map (i) -> 113 | if i.name? 114 | elements = 115 | if i.typeArgumentList.typeArguments.item 116 | [i.typeArgumentList.typeArguments.item] 117 | else if i.typeArgumentList.typeArguments 118 | i.typeArgumentList.typeArguments.elements 119 | else 120 | [] 121 | annotatedTypes = mapClass AnnotatedType, elements 122 | { 123 | typeName: walkSymbol(i.name) 124 | typeArguments: listToJSON annotatedTypes 125 | } 126 | else 127 | typeArgumentName: walkSymbol i 128 | 129 | toJSON: -> 130 | { 131 | nodeType: @constructor.name 132 | typeName: @typeName() 133 | typeArguments: @typeArguments() 134 | isArray: @isArray() 135 | } 136 | 137 | class TypeParameter extends Node 138 | ''' 139 | typeParameters: 140 | item: 141 | identifier: 142 | _fullText: T 143 | constraint: null 144 | ''' 145 | constructor: (@ast) -> 146 | 147 | toJSON: -> 148 | header = ":root > .typeParameters" 149 | items = @$(header + '> .item') 150 | items = 151 | if items.length > 0 then items 152 | else 153 | items = @$first(header+'> .elements')?.filter (i) -> i.identifier? 154 | items ?= [] 155 | items.map (i) -> 156 | { 157 | nodeType: @constructor.name 158 | typeParameterName: walkSymbol(i.identifier) 159 | constraint: i.constraint 160 | } 161 | 162 | class FunctionNode extends Node 163 | ''' 164 | Array 165 | 166 | typeAnnotation: 167 | _data: 0 168 | colonToken: 169 | _fullText: : 170 | tokenKind: 106 171 | _trailingTriviaInfo: 4 172 | type: 173 | _data: 0 174 | name: 175 | _fullText: Array 176 | tokenKind: 11 177 | typeArgumentList: 178 | _data: 0 179 | lessThanToken: 180 | tokenKind: 80 181 | typeArguments: 182 | item: 183 | _fullText: T 184 | tokenKind: 11 185 | greaterThanToken: 186 | tokenKind: 81 187 | ''' 188 | constructor: (@ast) -> 189 | 190 | propertyName: -> 191 | return walkSymbol @ast.propertyName if @ast.propertyName? 192 | return walkSymbol @ast.identifier if @ast.identifier? 193 | 194 | typeAnnotation: -> 195 | args = @_arguments() 196 | functionArgs = mapClass FunctionArgument, args 197 | returnType = new AnnotatedType @$first(':root > .callSignature > .typeAnnotation > .type') 198 | { 199 | nodeType: 'Function' 200 | returnType: returnType.toJSON() 201 | arguments: listToJSON functionArgs 202 | } 203 | 204 | _arguments: (query) -> 205 | header = ":root > .callSignature > .parameterList > .parameters" 206 | item = @$(header + '> .item') 207 | if item.length > 0 then item 208 | else 209 | args = @$first(header+'> .elements')?.filter (i) -> i.identifier? 210 | args ?= [] 211 | 212 | toJSON: -> 213 | propertyName: @propertyName() 214 | typeAnnotation: @typeAnnotation() 215 | typeParameters: if @ast.callSignature.typeParameterList? 216 | new TypeParameter(@ast.callSignature.typeParameterList).toJSON() 217 | else null 218 | 219 | class LambdaFunctionAnnotation extends Node 220 | ''' 221 | typeParameterList: null 222 | parameterList: 223 | _data: 0 224 | openParenToken: 225 | tokenKind: 72 226 | parameters: 227 | item: 228 | _data: 0 229 | dotDotDotToken: null 230 | modifiers: 231 | 232 | identifier: 233 | _fullText: t 234 | tokenKind: 11 235 | questionToken: null 236 | typeAnnotation: 237 | _data: 0 238 | colonToken: 239 | tokenKind: 106 240 | type: 241 | tokenKind: 67 242 | equalsValueClause: null 243 | closeParenToken: 244 | _fullText: ) 245 | tokenKind: 73 246 | _trailingTriviaInfo: 4 247 | equalsGreaterThanToken: 248 | _fullText: => 249 | tokenKind: 85 250 | _trailingTriviaInfo: 4 251 | type: 252 | tokenKind: 67 253 | ''' 254 | constructor: (@ast) -> 255 | 256 | arguments: (query) -> 257 | header = ":root > .parameterList > .parameters" 258 | item = @$(header + '> .item') 259 | if item.length > 0 then item 260 | else 261 | args = @$first(header+'> .elements')?.filter (i) -> i.identifier? 262 | args ?= [] 263 | 264 | _arguments: -> 265 | args = @arguments() 266 | identifiers = mapClass FunctionArgument, args 267 | args = identifiers.map (ident) => ident.toJSON() 268 | 269 | typeAnnotation: -> 270 | returnTypeAnnotation = new AnnotatedType @$first(':root > .type') 271 | returnTypeAnnotation.toJSON() 272 | 273 | toJSON: -> 274 | nodeType: @constructor.name 275 | annotationType: 'lambdaFunctionType' 276 | typeAnnotation: @typeAnnotation() 277 | arguments: @_arguments() 278 | 279 | class FunctionArgument extends Node 280 | ''' 281 | Example: str:string 282 | dotDotDotToken: null 283 | modifiers: 284 | 285 | identifier: 286 | _fullText: str 287 | tokenKind: 11 288 | questionToken: null 289 | typeAnnotation: 290 | _data: 0 291 | colonToken: 292 | tokenKind: 106 293 | type: 294 | tokenKind: 69 295 | equalsValueClause: null 296 | ''' 297 | 298 | constructor: (@ast) -> 299 | 300 | identifierName: -> walkSymbol @ast.identifier 301 | 302 | nullable: -> !!@ast.questionToken 303 | 304 | spriced: -> !!@ast.dotDotDotToken 305 | 306 | typeAnnotation: -> 307 | type = new AnnotatedType @$first(':root > .typeAnnotation > .type') 308 | type.toJSON() 309 | 310 | toJSON: -> 311 | nodeType: @constructor.name 312 | identifierName: @identifierName() 313 | typeAnnotation: @typeAnnotation() 314 | nullable: @nullable() 315 | spriced: @spriced() 316 | 317 | class VariableNode extends Node 318 | constructor: (@ast) -> 319 | 320 | propertyName: -> 321 | walkSymbol(@ast.variableDeclarator.propertyName) 322 | 323 | typeAnnotation: -> 324 | # TODO: refactor 325 | type = @$first(':root > .variableDeclarator > .typeAnnotation > .type') 326 | if type?.parameterList? 327 | lambdaFunctionAnnotation = new LambdaFunctionAnnotation(type) 328 | return lambdaFunctionAnnotation.toJSON() 329 | else 330 | type = new AnnotatedType @$first(':root > .variableDeclarator > .typeAnnotation > .type') 331 | return type.toJSON() 332 | 333 | toJSON: -> 334 | nodeType: @constructor.name 335 | propertyName: @propertyName() 336 | typeAnnotation: @typeAnnotation() 337 | 338 | class VariableDeclarationNode extends Node 339 | toJSON: -> 340 | { 341 | nodeType: @constructor.name 342 | propertyName: walkSymbol @ast.propertyName 343 | typeAnnotation: @typeAnnotation() 344 | } 345 | 346 | typeAnnotation: -> 347 | type = @$first(':root > .typeAnnotation > .type') 348 | if type?.parameterList? 349 | lambdaFunctionAnnotation = new LambdaFunctionAnnotation(type) 350 | return lambdaFunctionAnnotation.toJSON() 351 | else 352 | type = new AnnotatedType @$first(':root > .typeAnnotation > .type') 353 | type.toJSON() 354 | 355 | class HeritageList extends Node 356 | ''' 357 | nodeOrTokens: 358 | - 359 | extendsOrImplementsKeyword: 360 | _fullText: extends 361 | typeNames: 362 | item: 363 | _fullText: A 364 | - 365 | extendsOrImplementsKeyword: 366 | _fullText: implements 367 | typeNames: 368 | elements: 369 | - 370 | _fullText: IF1 371 | tokenKind: 11 372 | - 373 | _fullText: , 374 | tokenKind: 79 375 | - 376 | _fullText: IF2 377 | tokenKind: 11 378 | ''' 379 | root: 'heritageClauses' 380 | constructor: (@ast) -> 381 | toJSON: -> 382 | items = itemOrNodeOrTokens @ast 383 | implementList = null 384 | extend = null 385 | 386 | items.forEach (item) => 387 | heritageType = walkSymbol item.extendsOrImplementsKeyword 388 | types = itemOrElements(item.typeNames) 389 | .filter (i) -> i._fullText isnt ',' 390 | .map (i) -> new AnnotatedType(i) 391 | switch heritageType 392 | when 'implements' 393 | if types.length > 0 394 | implementList = listToJSON types 395 | when 'extends' 396 | if types.length > 0 397 | extend = types[0].toJSON() 398 | { 399 | implementList: implementList 400 | extend: extend 401 | } 402 | 403 | class ClassNode extends Node 404 | 405 | constructor: (@ast) -> 406 | 407 | getProperties: -> 408 | for el in @_classElements() 409 | if isFunctionNode(el) 410 | new FunctionNode(el) 411 | else 412 | new VariableNode(el) 413 | 414 | _classElements: -> 415 | item = @$(":root > .classElements > .item") 416 | if item.length > 0 then item 417 | else @$first(":root > .classElements > .nodeOrTokens") or [] 418 | 419 | className: -> walkSymbol @ast.identifier 420 | 421 | toJSON: -> 422 | { 423 | nodeType: @constructor.name 424 | className: @className() 425 | properties: listToJSON @getProperties() 426 | typeParameters: if @ast.typeParameterList? then new TypeParameter(@ast.typeParameterList).toJSON() else null 427 | heritages: if @ast.heritageClauses then new HeritageList(@ast.heritageClauses).toJSON() else null 428 | } 429 | 430 | class InterfaceNode extends Node 431 | ''' 432 | _data: 0 433 | modifiers: 434 | item: 435 | _fullText: export 436 | tokenKind: 47 437 | _trailingTriviaInfo: 4 438 | interfaceKeyword: 439 | _fullText: interface 440 | tokenKind: 52 441 | _trailingTriviaInfo: 4 442 | identifier: 443 | _fullText: IFoo 444 | tokenKind: 11 445 | _trailingTriviaInfo: 4 446 | typeParameterList: null 447 | heritageClauses: 448 | 449 | body: 450 | _data: 0 451 | openBraceToken: 452 | _fullText: { 453 | tokenKind: 70 454 | _trailingTriviaInfo: 5 455 | typeMembers: 456 | _data: 0 457 | elements: 458 | - 459 | _data: 0 460 | propertyName: 461 | _fullText: a 462 | tokenKind: 11 463 | _leadingTriviaInfo: 8 464 | questionToken: null 465 | typeAnnotation: 466 | _data: 0 467 | colonToken: 468 | tokenKind: 106 469 | type: 470 | tokenKind: 60 471 | - 472 | _fullText: ; 473 | tokenKind: 78 474 | _trailingTriviaInfo: 5 475 | - 476 | _data: 0 477 | propertyName: 478 | _fullText: b 479 | tokenKind: 11 480 | _leadingTriviaInfo: 8 481 | questionToken: null 482 | typeAnnotation: 483 | _data: 0 484 | colonToken: 485 | tokenKind: 106 486 | type: 487 | tokenKind: 67 488 | - 489 | _fullText: ; 490 | tokenKind: 78 491 | _trailingTriviaInfo: 5 492 | closeBraceToken: 493 | _fullText: } 494 | tokenKind: 71 495 | _trailingTriviaInfo: 5 496 | ''' 497 | 498 | constructor: (@ast) -> 499 | 500 | interfaceName: -> walkSymbol @ast.identifier 501 | 502 | properties: -> 503 | typeMembers = @$first(':root > .body > .typeMembers') 504 | props = [] 505 | if typeMembers.elements? 506 | for el in typeMembers.elements when el.propertyName 507 | props.push el 508 | else if typeMembers.item? 509 | props.push typeMembers.item 510 | 511 | props.map (i) => 512 | if isFunctionNode(i) 513 | new FunctionNode(i) 514 | else 515 | new VariableDeclarationNode(i) 516 | 517 | toJSON: -> 518 | { 519 | nodeType: @constructor.name 520 | interfaceName: @interfaceName() 521 | properties: listToJSON @properties() 522 | typeParameters: if @ast.typeParameterList? then new TypeParameter(@ast.typeParameterList).toJSON() else null 523 | heritages: if @ast.heritageClauses then new HeritageList(@ast.heritageClauses).toJSON() else null 524 | } 525 | 526 | exports.Module = Module = class Module extends Node 527 | 528 | constructor: (@ast) -> 529 | 530 | moduleName: -> 531 | return walkSymbol(@ast.item.name) if @ast.item?.name? 532 | return walkSymbol(@ast.name) if @ast.name? 533 | 534 | modules: -> 535 | item = @$(":root > .moduleElements > .item") 536 | if item.length > 0 then item 537 | else @$first(":root > .moduleElements > .nodeOrTokens") 538 | 539 | getModules: -> 540 | mods = @modules() 541 | mods = $(':root > *:has(.moduleKeyword)', mods)?.filter (m) -> m.moduleKeyword? 542 | mods ?= [] 543 | mapClass Module, mods 544 | 545 | getClasses: -> 546 | mods = @modules() 547 | mods = $(':root > *:has(.classKeyword)', mods)?.filter (c) -> c.classKeyword? 548 | mods ?= [] 549 | mapClass ClassNode, mods 550 | 551 | getInterfaces: -> 552 | mods = @modules() 553 | mods = $(':root > *:has(.interfaceKeyword)', mods)?.filter (c) -> c.interfaceKeyword? 554 | mods ?= [] 555 | mapClass InterfaceNode, mods 556 | 557 | getFunctions: -> 558 | mods = @modules() 559 | mods = $(':root > *:has(.functionKeyword)', mods)?.filter (f) -> f.functionKeyword? 560 | mods ?= [] 561 | mapClass FunctionNode, mods 562 | 563 | getVariables: -> 564 | mods = @modules() 565 | mods = $(':root > *:has(:root .variableDeclaration)', mods)?.filter (v) -> v.variableDeclaration? 566 | 567 | items = [] 568 | mods.forEach (m) -> 569 | if elements = m.variableDeclaration.variableDeclarators.elements 570 | for el in elements when el.propertyName 571 | items.push el 572 | else if item = m.variableDeclaration.variableDeclarators.item 573 | items.push item 574 | mapClass VariableDeclarationNode, items 575 | 576 | getProperties: -> 577 | props = [] 578 | [].concat(@getFunctions(), @getVariables()) 579 | 580 | toJSON: -> 581 | nodeType: @constructor.name 582 | moduleName: @moduleName() 583 | modules : listToJSON @getModules() 584 | classes : listToJSON @getClasses() 585 | properties: listToJSON @getProperties() 586 | interfaces: listToJSON @getInterfaces() 587 | 588 | exports.TopModule = TopModule = class TopModule extends Module 589 | moduleName: -> 'Top' 590 | constructor: (@ast) -> 591 | -------------------------------------------------------------------------------- /src/parser.coffee: -------------------------------------------------------------------------------- 1 | $ = require('JSONSelect').match 2 | TypeScript = require './typescript' 3 | 4 | module.exports = class DTSParser 5 | preprocess: (ast) -> 6 | [ 7 | '_fullText' 8 | 'typeKind' 9 | ].forEach (name) -> 10 | $(":has(.#{name})", ast).forEach (item) -> 11 | text = item[name]?.replace? /\s/g, '' 12 | item[name] = text 13 | 14 | parse: (source) -> 15 | source = source.replace /\/\*([\s\S]*?)\*\//g, '' 16 | source = source.replace /\/\/.*\n/g, '' 17 | 18 | ast = TypeScript.Parser.parse( 19 | 'dummy.ts', 20 | TypeScript.SimpleText.fromString(source), 21 | true, 22 | new TypeScript.ParseOptions(TypeScript.LanguageVersion.EcmaScript5, true)) 23 | @preprocess ast 24 | ast 25 | -------------------------------------------------------------------------------- /src/typescript.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | eval fs.readFileSync(__dirname+'/../node_modules/typescript/bin/typescript.js').toString() 3 | module.exports = TypeScript 4 | -------------------------------------------------------------------------------- /test/fixtures/arrayable.d.ts: -------------------------------------------------------------------------------- 1 | export var a: Object[]; 2 | -------------------------------------------------------------------------------- /test/fixtures/comments.d.ts: -------------------------------------------------------------------------------- 1 | /* */ 2 | export var x: number; //aaaaa 3 | //bbb 4 | -------------------------------------------------------------------------------- /test/fixtures/dot.d.ts: -------------------------------------------------------------------------------- 1 | interface AAA { 2 | concat(...items: T[]): LoDashArrayWrapper; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/dummy.d.ts: -------------------------------------------------------------------------------- 1 | declare module Foo { 2 | export function fun(str?: number[]):void; 3 | export var a:number; 4 | export class Bar { 5 | x: any; 6 | } 7 | } 8 | 9 | export class X {} 10 | export var x: any; 11 | 12 | export interface IFoo { 13 | s: string; 14 | f: (t:number) => Object[]; 15 | } 16 | 17 | export interface IFoo2 extends IFOO { 18 | n : number; 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/exported_function.d.ts: -------------------------------------------------------------------------------- 1 | declare module Foo { 2 | export function fun(str: string):void; 3 | export function funfun(str: string):void; 4 | export var a:number, b: Object; 5 | export var c: Object; 6 | export class Bar { 7 | f():string; 8 | x: any; 9 | } 10 | } 11 | 12 | export class X {} 13 | export var x: any; 14 | 15 | /* 16 | moduleName: Top 17 | modules: 18 | - 19 | moduleName: Foo 20 | modules: 21 | (empty array) 22 | classes: 23 | - 24 | className: Bar 25 | properties: 26 | - 27 | typeAnnotation: 28 | annotationType: functionType 29 | returnTypeName: String 30 | arguments: 31 | (empty array) 32 | - 33 | propertyName: x 34 | typeAnnotation: 35 | nodeType: identifierType 36 | typeName: Any 37 | properties: 38 | - 39 | propertyName: fun 40 | typeAnnotation: 41 | annotationType: functionType 42 | returnTypeName: Void 43 | arguments: 44 | - 45 | identifierName: str 46 | typeAnnotation: String 47 | - 48 | propertyName: funfun 49 | typeAnnotation: 50 | annotationType: functionType 51 | returnTypeName: Void 52 | arguments: 53 | - 54 | identifierName: str 55 | typeAnnotation: String 56 | - 57 | propertyName: 58 | - a 59 | typeAnnotation: 60 | nodeType: identifierType 61 | typeName: Number 62 | - 63 | propertyName: 64 | - b 65 | typeAnnotation: 66 | nodeType: identifierType 67 | typeName: Object 68 | - 69 | propertyName: 70 | - c 71 | typeAnnotation: 72 | nodeType: identifierType 73 | typeName: Object 74 | classes: 75 | - 76 | className: X 77 | properties: 78 | (empty array) 79 | properties: 80 | - 81 | propertyName: 82 | - x 83 | typeAnnotation: 84 | nodeType: identifierType 85 | typeName: Any 86 | */ 87 | -------------------------------------------------------------------------------- /test/fixtures/extends.d.ts: -------------------------------------------------------------------------------- 1 | interface IF1{} 2 | interface IF2{} 3 | export class A {}; 4 | export class B extends A implements IF1, IF2 {} 5 | -------------------------------------------------------------------------------- /test/fixtures/function.d.ts: -------------------------------------------------------------------------------- 1 | declare module Foo { 2 | export class Hoge { 3 | s: any; 4 | f1(str:string, n: number, obj: Object): number; 5 | f2: (str:string, n: number, obj: Object) => number; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/generics.d.ts: -------------------------------------------------------------------------------- 1 | interface Identity {} 2 | 3 | class Cls {} 4 | 5 | interface Id { 6 | id(t: Array>): number; 7 | idx(t: number): Array; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/interface.d.ts: -------------------------------------------------------------------------------- 1 | export interface IFoo { 2 | s: string; 3 | f: (t:number) => Object; 4 | } 5 | 6 | export interface IEFoo extends IFOO { 7 | n : number; 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/multi_module.d.ts: -------------------------------------------------------------------------------- 1 | declare module Foo { 2 | export module Bar { 3 | export module Baz {} 4 | } 5 | } 6 | declare module Hoge {} 7 | -------------------------------------------------------------------------------- /test/fixtures/nested.d.ts: -------------------------------------------------------------------------------- 1 | module A.B { 2 | export interface Point { 3 | x : number; 4 | y : number; 5 | } 6 | } 7 | module A { 8 | export var array: A.B.Point[]; 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/nullable.d.ts: -------------------------------------------------------------------------------- 1 | export function f(a?:any): void; 2 | -------------------------------------------------------------------------------- /test/parse-test.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | path = require 'path' 3 | dts = require '../index' 4 | assert = require 'assert' 5 | 6 | targets = [ 7 | 'arrayable.d.ts' 8 | 'comments.d.ts' 9 | 'dot.d.ts' 10 | 'dummy.d.ts' 11 | 'exported_function.d.ts' 12 | 'extends.d.ts' 13 | 'function.d.ts' 14 | 'generics.d.ts' 15 | 'interface.d.ts' 16 | 'multi_module.d.ts' 17 | 'nullable.d.ts' 18 | ] 19 | 20 | describe '#parse', -> 21 | targets.map (target) => 22 | it target, -> 23 | preparsed = JSON.parse fs.readFileSync(path.join __dirname,'parsed/'+target+'.json').toString() 24 | source = fs.readFileSync(path.join __dirname ,'fixtures/'+target).toString() 25 | parsed = dts.parse(source) 26 | assert.equal JSON.stringify(parsed), JSON.stringify(preparsed) 27 | 28 | # FIXME: I want to use deepEqual but doesn't works comparing json 29 | # assert.deepEqual parsed, preparsed 30 | -------------------------------------------------------------------------------- /test/parsed/arrayable.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[],"properties":[{"nodeType":"VariableDeclarationNode","propertyName":"a","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":true}}],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/comments.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[],"properties":[{"nodeType":"VariableDeclarationNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}}],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/dot.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[],"properties":[],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"AAA","properties":[{"propertyName":"concat","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"LoDashArrayWrapper","typeArguments":[{"typeArgumentName":"T"}],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"items","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"T","typeArguments":[],"isArray":true},"nullable":false,"spriced":true}]},"typeParameters":null}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}]} -------------------------------------------------------------------------------- /test/parsed/dummy.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[{"nodeType":"Module","moduleName":"Foo","modules":[],"classes":[{"nodeType":"ClassNode","className":"Bar","properties":[{"nodeType":"VariableNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false}}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}],"properties":[{"propertyName":"fun","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Void","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"str","typeAnnotation":{"nodeType":"AnnotatedType","typeArguments":[],"isArray":true},"nullable":true,"spriced":false}]},"typeParameters":null},{"nodeType":"VariableDeclarationNode","propertyName":"a","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}}],"interfaces":[]}],"classes":[{"nodeType":"ClassNode","className":"X","properties":[],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}],"properties":[{"nodeType":"VariableDeclarationNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false}}],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"IFoo","properties":[{"nodeType":"VariableDeclarationNode","propertyName":"s","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false}},{"nodeType":"VariableDeclarationNode","propertyName":"f","typeAnnotation":{"nodeType":"LambdaFunctionAnnotation","annotationType":"lambdaFunctionType","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":true},"arguments":[{"nodeType":"FunctionArgument","identifierName":"t","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]}}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}},{"nodeType":"InterfaceNode","interfaceName":"IFoo2","properties":[{"nodeType":"VariableDeclarationNode","propertyName":"n","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}}],"typeParameters":null,"heritages":{"implementList":null,"extend":{"nodeType":"AnnotatedType","typeName":"IFOO","typeArguments":[],"isArray":false}}}]} -------------------------------------------------------------------------------- /test/parsed/exported_function.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[{"nodeType":"Module","moduleName":"Foo","modules":[],"classes":[{"nodeType":"ClassNode","className":"Bar","properties":[{"propertyName":"f","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false},"arguments":[]},"typeParameters":null},{"nodeType":"VariableNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false}}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}],"properties":[{"propertyName":"fun","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Void","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"str","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]},"typeParameters":null},{"propertyName":"funfun","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Void","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"str","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]},"typeParameters":null},{"nodeType":"VariableDeclarationNode","propertyName":"a","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}},{"nodeType":"VariableDeclarationNode","propertyName":"b","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":false}},{"nodeType":"VariableDeclarationNode","propertyName":"c","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":false}}],"interfaces":[]}],"classes":[{"nodeType":"ClassNode","className":"X","properties":[],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}],"properties":[{"nodeType":"VariableDeclarationNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false}}],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/extends.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[{"nodeType":"ClassNode","className":"A","properties":[],"typeParameters":null,"heritages":{"implementList":null,"extend":null}},{"nodeType":"ClassNode","className":"B","properties":[],"typeParameters":null,"heritages":{"implementList":[{"nodeType":"AnnotatedType","typeName":"IF1","typeArguments":[],"isArray":false},{"nodeType":"AnnotatedType","typeName":"IF2","typeArguments":[{"typeArgumentName":"Object"}],"isArray":false}],"extend":{"nodeType":"AnnotatedType","typeName":"A","typeArguments":[],"isArray":false}}}],"properties":[],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"IF1","properties":[],"typeParameters":null,"heritages":{"implementList":null,"extend":null}},{"nodeType":"InterfaceNode","interfaceName":"IF2","properties":[],"typeParameters":[{"nodeType":"Object","typeParameterName":"T","constraint":null}],"heritages":{"implementList":null,"extend":null}}]} -------------------------------------------------------------------------------- /test/parsed/function.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[{"nodeType":"Module","moduleName":"Foo","modules":[],"classes":[{"nodeType":"ClassNode","className":"Hoge","properties":[{"nodeType":"VariableNode","propertyName":"s","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false}},{"propertyName":"f1","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"str","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false},"nullable":false,"spriced":false},{"nodeType":"FunctionArgument","identifierName":"n","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"nullable":false,"spriced":false},{"nodeType":"FunctionArgument","identifierName":"obj","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]},"typeParameters":null},{"nodeType":"VariableNode","propertyName":"f2","typeAnnotation":{"nodeType":"LambdaFunctionAnnotation","annotationType":"lambdaFunctionType","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"str","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false},"nullable":false,"spriced":false},{"nodeType":"FunctionArgument","identifierName":"n","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"nullable":false,"spriced":false},{"nodeType":"FunctionArgument","identifierName":"obj","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]}}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}],"properties":[],"interfaces":[]}],"classes":[],"properties":[],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/generics.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[{"nodeType":"ClassNode","className":"Cls","properties":[],"typeParameters":[{"nodeType":"Object","typeParameterName":"T","constraint":null},{"nodeType":"Object","typeParameterName":"U","constraint":null}],"heritages":{"implementList":null,"extend":null}}],"properties":[],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"Identity","properties":[],"typeParameters":[{"nodeType":"Object","typeParameterName":"T","constraint":null},{"nodeType":"Object","typeParameterName":"U","constraint":null}],"heritages":{"implementList":null,"extend":null}},{"nodeType":"InterfaceNode","interfaceName":"Id","properties":[{"propertyName":"id","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"t","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Array","typeArguments":[{"typeName":"Array","typeArguments":[{"nodeType":"AnnotatedType","typeName":"T","typeArguments":[],"isArray":false}]}],"isArray":false},"nullable":false,"spriced":false}]},"typeParameters":[{"nodeType":"Object","typeParameterName":"T","constraint":null}]},{"propertyName":"idx","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Array","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"t","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]},"typeParameters":null}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}}]} -------------------------------------------------------------------------------- /test/parsed/interface.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[],"properties":[],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"IFoo","properties":[{"nodeType":"VariableDeclarationNode","propertyName":"s","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"String","typeArguments":[],"isArray":false}},{"nodeType":"VariableDeclarationNode","propertyName":"f","typeAnnotation":{"nodeType":"LambdaFunctionAnnotation","annotationType":"lambdaFunctionType","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Object","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"t","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false},"nullable":false,"spriced":false}]}}],"typeParameters":null,"heritages":{"implementList":null,"extend":null}},{"nodeType":"InterfaceNode","interfaceName":"IEFoo","properties":[{"nodeType":"VariableDeclarationNode","propertyName":"n","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}}],"typeParameters":null,"heritages":{"implementList":null,"extend":{"nodeType":"AnnotatedType","typeName":"IFOO","typeArguments":[],"isArray":false}}}]} -------------------------------------------------------------------------------- /test/parsed/multi_module.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[{"nodeType":"Module","moduleName":"Foo","modules":[{"nodeType":"Module","moduleName":"Bar","modules":[{"nodeType":"Module","moduleName":"Baz","modules":[],"classes":[],"properties":[],"interfaces":[]}],"classes":[],"properties":[],"interfaces":[]}],"classes":[],"properties":[],"interfaces":[]},{"nodeType":"Module","moduleName":"Hoge","modules":[],"classes":[],"properties":[],"interfaces":[]}],"classes":[],"properties":[],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/nested.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[{"nodeType":"Module","moduleName":{"left":"A","right":"B","nodeType":"MemberAccess"},"modules":[],"classes":[],"properties":[],"interfaces":[{"nodeType":"InterfaceNode","interfaceName":"Point","properties":[{"nodeType":"VariableDeclarationNode","propertyName":"x","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}},{"nodeType":"VariableDeclarationNode","propertyName":"y","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Number","typeArguments":[],"isArray":false}}],"typeParameters":[{"nodeType":"Object","typeParameterName":"T","constraint":null}],"heritages":{"implementList":null,"extend":null}}]},{"nodeType":"Module","moduleName":"A","modules":[],"classes":[],"properties":[{"nodeType":"VariableDeclarationNode","propertyName":"array","typeAnnotation":{"nodeType":"AnnotatedType","typeName":{"left":{"left":"A","right":"B","nodeType":"MemberAccess"},"right":"Point","nodeType":"MemberAccess"},"typeArguments":[],"isArray":true}}],"interfaces":[]}],"classes":[],"properties":[],"interfaces":[]} -------------------------------------------------------------------------------- /test/parsed/nullable.d.ts.json: -------------------------------------------------------------------------------- 1 | {"nodeType":"TopModule","moduleName":"Top","modules":[],"classes":[],"properties":[{"propertyName":"f","typeAnnotation":{"nodeType":"Function","returnType":{"nodeType":"AnnotatedType","typeName":"Void","typeArguments":[],"isArray":false},"arguments":[{"nodeType":"FunctionArgument","identifierName":"a","typeAnnotation":{"nodeType":"AnnotatedType","typeName":"Any","typeArguments":[],"isArray":false},"nullable":true,"spriced":false}]},"typeParameters":null}],"interfaces":[]} -------------------------------------------------------------------------------- /update-fixtures: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | Dir::glob('test/fixtures/*').each {|fpath| 3 | puts `./bin/dts-parser -w -o test/parsed #{fpath}` 4 | } 5 | --------------------------------------------------------------------------------