OLD | NEW |
1 import * as dartStyle from 'dart-style'; | 1 import * as dartStyle from 'dart-style'; |
2 import * as path from 'path'; | 2 import * as path from 'path'; |
3 import * as ts from 'typescript'; | 3 import * as ts from 'typescript'; |
4 | 4 |
5 import {OutputContext, Transpiler} from './main'; | 5 import {OutputContext, Transpiler} from './main'; |
6 | 6 |
7 /** | 7 /** |
8 * Map from identifier name to resolved type. | 8 * Map from identifier name to resolved type. |
9 * Example: 'E' should map to a TypeNode for number when resolving a usage of My
Array<number> | 9 * Example: 'E' should map to a TypeNode for number when resolving a usage of My
Array<number> |
10 * where MyArray is the alias type: | 10 * where MyArray is the alias type: |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 case ts.SyntaxKind.FunctionType: | 243 case ts.SyntaxKind.FunctionType: |
244 case ts.SyntaxKind.ThisType: | 244 case ts.SyntaxKind.ThisType: |
245 return true; | 245 return true; |
246 default: | 246 default: |
247 return false; | 247 return false; |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 export function isCallable(decl: ClassLike): boolean { | 251 export function isCallable(decl: ClassLike): boolean { |
252 let members = decl.members as Array<ts.ClassElement>; | 252 let members = decl.members as Array<ts.ClassElement>; |
253 return members.some((member) => { return member.kind === ts.SyntaxKind.CallSig
nature; }); | 253 return members.some((member) => { |
| 254 return member.kind === ts.SyntaxKind.CallSignature; |
| 255 }); |
254 } | 256 } |
255 | 257 |
256 export function copyLocation(src: ts.TextRange, dest: ts.TextRange) { | 258 export function copyLocation(src: ts.TextRange, dest: ts.TextRange) { |
257 dest.pos = src.pos; | 259 dest.pos = src.pos; |
258 dest.end = src.end; | 260 dest.end = src.end; |
259 } | 261 } |
260 | 262 |
261 // Polyfill for ES6 Array.find. | 263 // Polyfill for ES6 Array.find. |
262 export function arrayFindPolyfill<T>( | 264 export function arrayFindPolyfill<T>( |
263 nodeArray: ts.NodeArray<T>, predicate: (node: T) => boolean): T { | 265 nodeArray: ts.NodeArray<T>, predicate: (node: T) => boolean): T { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 sb += comment; | 323 sb += comment; |
322 sb += '*/'; | 324 sb += '*/'; |
323 return sb; | 325 return sb; |
324 } | 326 } |
325 } | 327 } |
326 | 328 |
327 export class TranspilerBase { | 329 export class TranspilerBase { |
328 private idCounter: number = 0; | 330 private idCounter: number = 0; |
329 constructor(protected transpiler: Transpiler) {} | 331 constructor(protected transpiler: Transpiler) {} |
330 | 332 |
331 visit(n: ts.Node) { this.transpiler.visit(n); } | 333 visit(n: ts.Node) { |
332 pushContext(context: OutputContext) { this.transpiler.pushContext(context); } | 334 this.transpiler.visit(n); |
333 popContext() { this.transpiler.popContext(); } | 335 } |
334 emit(s: string) { this.transpiler.emit(s); } | 336 pushContext(context: OutputContext) { |
335 emitNoSpace(s: string) { this.transpiler.emitNoSpace(s); } | 337 this.transpiler.pushContext(context); |
336 emitType(s: string, comment: string) { this.transpiler.emitType(s, comment); } | 338 } |
337 maybeLineBreak() { return this.transpiler.maybeLineBreak(); } | 339 popContext() { |
338 enterCodeComment() { return this.transpiler.enterCodeComment(); } | 340 this.transpiler.popContext(); |
339 exitCodeComment() { return this.transpiler.exitCodeComment(); } | 341 } |
| 342 emit(s: string) { |
| 343 this.transpiler.emit(s); |
| 344 } |
| 345 emitNoSpace(s: string) { |
| 346 this.transpiler.emitNoSpace(s); |
| 347 } |
| 348 emitType(s: string, comment: string) { |
| 349 this.transpiler.emitType(s, comment); |
| 350 } |
| 351 maybeLineBreak() { |
| 352 return this.transpiler.maybeLineBreak(); |
| 353 } |
| 354 enterCodeComment() { |
| 355 return this.transpiler.enterCodeComment(); |
| 356 } |
| 357 exitCodeComment() { |
| 358 return this.transpiler.exitCodeComment(); |
| 359 } |
340 | 360 |
341 enterTypeArguments() { this.transpiler.enterTypeArgument(); } | 361 enterTypeArguments() { |
342 exitTypeArguments() { this.transpiler.exitTypeArgument(); } | 362 this.transpiler.enterTypeArgument(); |
343 get insideTypeArgument() { return this.transpiler.insideTypeArgument; } | 363 } |
| 364 exitTypeArguments() { |
| 365 this.transpiler.exitTypeArgument(); |
| 366 } |
| 367 get insideTypeArgument() { |
| 368 return this.transpiler.insideTypeArgument; |
| 369 } |
344 | 370 |
345 get insideCodeComment() { return this.transpiler.insideCodeComment; } | 371 get insideCodeComment() { |
| 372 return this.transpiler.insideCodeComment; |
| 373 } |
346 | 374 |
347 getImportSummary(libraryUri: string): ImportSummary { | 375 getImportSummary(libraryUri: string): ImportSummary { |
348 if (!Object.hasOwnProperty.call(this.transpiler.imports, libraryUri)) { | 376 if (!Object.hasOwnProperty.call(this.transpiler.imports, libraryUri)) { |
349 let summary = new ImportSummary(); | 377 let summary = new ImportSummary(); |
350 this.transpiler.imports[libraryUri] = summary; | 378 this.transpiler.imports[libraryUri] = summary; |
351 return summary; | 379 return summary; |
352 } | 380 } |
353 return this.transpiler.imports[libraryUri]; | 381 return this.transpiler.imports[libraryUri]; |
354 } | 382 } |
355 | 383 |
(...skipping 27 matching lines...) Expand all Loading... |
383 let parts = this.getDartFileName(relativePath).split('/'); | 411 let parts = this.getDartFileName(relativePath).split('/'); |
384 let fileName = parts[parts.length - 1]; | 412 let fileName = parts[parts.length - 1]; |
385 let identifierParts = identifier.split('.'); | 413 let identifierParts = identifier.split('.'); |
386 identifier = identifierParts[identifierParts.length - 1]; | 414 identifier = identifierParts[identifierParts.length - 1]; |
387 let summary = this.addImport(this.transpiler.getDartFileName(fileName), iden
tifier); | 415 let summary = this.addImport(this.transpiler.getDartFileName(fileName), iden
tifier); |
388 if (summary.asPrefix) return summary.asPrefix + '.' + identifier; | 416 if (summary.asPrefix) return summary.asPrefix + '.' + identifier; |
389 return identifier; | 417 return identifier; |
390 } | 418 } |
391 | 419 |
392 | 420 |
393 reportError(n: ts.Node, message: string) { this.transpiler.reportError(n, mess
age); } | 421 reportError(n: ts.Node, message: string) { |
| 422 this.transpiler.reportError(n, message); |
| 423 } |
394 | 424 |
395 visitNode(n: ts.Node): boolean { throw new Error('not implemented'); } | 425 visitNode(n: ts.Node): boolean { |
| 426 throw new Error('not implemented'); |
| 427 } |
396 | 428 |
397 visitEach(nodes: ts.Node[]) { nodes.forEach((n) => this.visit(n)); } | 429 visitEach(nodes: ts.Node[]) { |
| 430 nodes.forEach((n) => this.visit(n)); |
| 431 } |
398 | 432 |
399 visitEachIfPresent(nodes?: ts.Node[]) { | 433 visitEachIfPresent(nodes?: ts.Node[]) { |
400 if (nodes) this.visitEach(nodes); | 434 if (nodes) this.visitEach(nodes); |
401 } | 435 } |
402 | 436 |
403 visitList(nodes: ts.Node[], separator = ',') { | 437 visitList(nodes: ts.Node[], separator = ',') { |
404 for (let i = 0; i < nodes.length; i++) { | 438 for (let i = 0; i < nodes.length; i++) { |
405 this.visit(nodes[i]); | 439 this.visit(nodes[i]); |
406 if (i < nodes.length - 1) this.emitNoSpace(separator); | 440 if (i < nodes.length - 1) this.emitNoSpace(separator); |
407 } | 441 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 } | 478 } |
445 } | 479 } |
446 | 480 |
447 getAncestor(n: ts.Node, kind: ts.SyntaxKind): ts.Node { | 481 getAncestor(n: ts.Node, kind: ts.SyntaxKind): ts.Node { |
448 for (let parent = n; parent; parent = parent.parent) { | 482 for (let parent = n; parent; parent = parent.parent) { |
449 if (parent.kind === kind) return parent; | 483 if (parent.kind === kind) return parent; |
450 } | 484 } |
451 return null; | 485 return null; |
452 } | 486 } |
453 | 487 |
454 hasAncestor(n: ts.Node, kind: ts.SyntaxKind): boolean { return !!getAncestor(n
, kind); } | 488 hasAncestor(n: ts.Node, kind: ts.SyntaxKind): boolean { |
| 489 return !!getAncestor(n, kind); |
| 490 } |
455 | 491 |
456 hasAnnotation(decorators: ts.NodeArray<ts.Decorator>, name: string): boolean { | 492 hasAnnotation(decorators: ts.NodeArray<ts.Decorator>, name: string): boolean { |
457 if (!decorators) return false; | 493 if (!decorators) return false; |
458 return decorators.some((d) => { | 494 return decorators.some((d) => { |
459 let decName = ident(d.expression); | 495 let decName = ident(d.expression); |
460 if (decName === name) return true; | 496 if (decName === name) return true; |
461 if (d.expression.kind !== ts.SyntaxKind.CallExpression) return false; | 497 if (d.expression.kind !== ts.SyntaxKind.CallExpression) return false; |
462 let callExpr = (<ts.CallExpression>d.expression); | 498 let callExpr = (<ts.CallExpression>d.expression); |
463 decName = ident(callExpr.expression); | 499 decName = ident(callExpr.expression); |
464 return decName === name; | 500 return decName === name; |
465 }); | 501 }); |
466 } | 502 } |
467 | 503 |
468 hasFlag(n: {flags: number}, flag: ts.NodeFlags): boolean { | 504 hasFlag(n: {flags: number}, flag: ts.NodeFlags): boolean { |
469 return n && (n.flags & flag) !== 0 || false; | 505 return n && (n.flags & flag) !== 0 || false; |
470 } | 506 } |
471 | 507 |
472 getRelativeFileName(fileName: string): string { | 508 getRelativeFileName(fileName: string): string { |
473 return this.transpiler.getRelativeFileName(fileName); | 509 return this.transpiler.getRelativeFileName(fileName); |
474 } | 510 } |
475 | 511 |
476 getDartFileName(fileName?: string): string { return this.transpiler.getDartFil
eName(fileName); } | 512 getDartFileName(fileName?: string): string { |
| 513 return this.transpiler.getDartFileName(fileName); |
| 514 } |
477 | 515 |
478 maybeVisitTypeArguments(n: {typeArguments?: ts.NodeArray<ts.TypeNode>}) { | 516 maybeVisitTypeArguments(n: {typeArguments?: ts.NodeArray<ts.TypeNode>}) { |
479 if (n.typeArguments) { | 517 if (n.typeArguments) { |
480 this.emitNoSpace('<'); | 518 this.emitNoSpace('<'); |
481 this.enterTypeArguments(); | 519 this.enterTypeArguments(); |
482 this.visitList(n.typeArguments); | 520 this.visitList(n.typeArguments); |
483 this.exitTypeArguments(); | 521 this.exitTypeArguments(); |
484 this.emitNoSpace('>'); | 522 this.emitNoSpace('>'); |
485 } | 523 } |
486 } | 524 } |
(...skipping 21 matching lines...) Expand all Loading... |
508 if (hasValidParameters) this.emitNoSpace(','); | 546 if (hasValidParameters) this.emitNoSpace(','); |
509 let positionalOptional = parameters.slice(firstInitParamIdx, parameters.le
ngth); | 547 let positionalOptional = parameters.slice(firstInitParamIdx, parameters.le
ngth); |
510 this.emit('['); | 548 this.emit('['); |
511 this.visitParameterList(positionalOptional); | 549 this.visitParameterList(positionalOptional); |
512 this.emitNoSpace(']'); | 550 this.emitNoSpace(']'); |
513 } | 551 } |
514 | 552 |
515 this.emitNoSpace(')'); | 553 this.emitNoSpace(')'); |
516 } | 554 } |
517 } | 555 } |
OLD | NEW |