| OLD | NEW | 
|---|
|  | 1 import * as dartStyle from 'dart-style'; | 
| 1 import * as fs from 'fs'; | 2 import * as fs from 'fs'; | 
| 2 import * as path from 'path'; | 3 import * as path from 'path'; | 
| 3 import * as ts from 'typescript'; | 4 import * as ts from 'typescript'; | 
| 4 | 5 | 
| 5 import * as base from './base'; | 6 import * as base from './base'; | 
| 6 import {Set, TranspilerBase} from './base'; | 7 import {Set, TranspilerBase} from './base'; | 
| 7 | 8 import DeclarationTranspiler from './declaration'; | 
|  | 9 import {FacadeConverter, NameRewriter} from './facade_converter'; | 
|  | 10 import * as merge from './merge'; | 
| 8 import mkdirP from './mkdirp'; | 11 import mkdirP from './mkdirp'; | 
| 9 import DeclarationTranspiler from './declaration'; |  | 
| 10 import * as merge from './merge'; |  | 
| 11 import ModuleTranspiler from './module'; | 12 import ModuleTranspiler from './module'; | 
| 12 import TypeTranspiler from './type'; | 13 import TypeTranspiler from './type'; | 
| 13 import {FacadeConverter, NameRewriter} from './facade_converter'; |  | 
| 14 import * as dartStyle from 'dart-style'; |  | 
| 15 | 14 | 
| 16 export interface TranspilerOptions { | 15 export interface TranspilerOptions { | 
| 17   /** | 16   /** | 
| 18    * Fail on the first error, do not collect multiple. Allows easier debugging a
     s stack traces lead | 17    * Fail on the first error, do not collect multiple. Allows easier debugging a
     s stack traces lead | 
| 19    * directly to the offending line. | 18    * directly to the offending line. | 
| 20    */ | 19    */ | 
| 21   failFast?: boolean; | 20   failFast?: boolean; | 
| 22   /** Whether to generate 'library a.b.c;' names from relative file paths. */ | 21   /** | 
| 23   generateLibraryName?: boolean; | 22    * Pass in a module name (e.g.) d3 instead of determining the module name fro 
     the d.ts files. | 
|  | 23    * This is useful when using libraries that assume they will be loaded with a 
     JS module loader | 
|  | 24    * without having to use a JS module loader. | 
|  | 25    */ | 
|  | 26   moduleName?: string; | 
| 24   /** | 27   /** | 
| 25    * A base path to relativize absolute file paths against. This is useful for l
     ibrary name | 28    * A base path to relativize absolute file paths against. This is useful for l
     ibrary name | 
| 26    * generation (see above) and nicer file names in error messages. | 29    * generation (see above) and nicer file names in error messages. | 
| 27    */ | 30    */ | 
| 28   basePath?: string; | 31   basePath?: string; | 
| 29   /** | 32   /** | 
| 30    * Use dart:html instead of the raw JavaScript DOM when generated Dart code. |  | 
| 31    */ |  | 
| 32   useHtml?: boolean; |  | 
| 33   /** |  | 
| 34    * Enforce conventions of public/private keyword and underscore prefix | 33    * Enforce conventions of public/private keyword and underscore prefix | 
| 35    */ | 34    */ | 
| 36   enforceUnderscoreConventions?: boolean; | 35   enforceUnderscoreConventions?: boolean; | 
| 37   /** | 36   /** | 
| 38    * Sets a root path to look for typings used by the facade converter. | 37    * Sets a root path to look for typings used by the facade converter. | 
| 39    */ | 38    */ | 
| 40   typingsRoot?: string; | 39   typingsRoot?: string; | 
| 41 | 40 | 
| 42   /** | 41   /** | 
| 43    * Experimental JS Interop specific option to promote properties with function | 42    * Experimental JS Interop specific option to promote properties with function | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 75   importsEmitted: Set; | 74   importsEmitted: Set; | 
| 76   // Comments attach to all following AST nodes before the next 'physical' token
     . Track the earliest | 75   // Comments attach to all following AST nodes before the next 'physical' token
     . Track the earliest | 
| 77   // offset to avoid printing comments multiple times. | 76   // offset to avoid printing comments multiple times. | 
| 78   private lastCommentIdx: number = -1; | 77   private lastCommentIdx: number = -1; | 
| 79   private errors: string[] = []; | 78   private errors: string[] = []; | 
| 80 | 79 | 
| 81   private transpilers: TranspilerBase[]; | 80   private transpilers: TranspilerBase[]; | 
| 82   private declarationTranspiler: DeclarationTranspiler; | 81   private declarationTranspiler: DeclarationTranspiler; | 
| 83   private fc: FacadeConverter; | 82   private fc: FacadeConverter; | 
| 84   private nameRewriter: NameRewriter; | 83   private nameRewriter: NameRewriter; | 
|  | 84   private typeArgumentDepth = 0; | 
| 85 | 85 | 
| 86   constructor(private options: TranspilerOptions = {}) { | 86   constructor(private options: TranspilerOptions = {}) { | 
| 87     this.nameRewriter = new NameRewriter(); | 87     this.nameRewriter = new NameRewriter(); | 
| 88     this.fc = new FacadeConverter(this, options.typingsRoot, this.nameRewriter, 
     options.useHtml); | 88     this.fc = new FacadeConverter(this, options.typingsRoot, this.nameRewriter); | 
| 89     this.declarationTranspiler = new DeclarationTranspiler( | 89     this.declarationTranspiler = new DeclarationTranspiler( | 
| 90         this, this.fc, options.enforceUnderscoreConventions, options.promoteFunc
     tionLikeMembers); | 90         this, this.fc, options.enforceUnderscoreConventions, options.promoteFunc
     tionLikeMembers); | 
| 91     this.transpilers = [ | 91     this.transpilers = [ | 
|  | 92       new ModuleTranspiler(this, this.fc, options.moduleName), | 
| 92       this.declarationTranspiler, | 93       this.declarationTranspiler, | 
| 93       new ModuleTranspiler(this, this.fc, options.generateLibraryName), |  | 
| 94       new TypeTranspiler(this, this.fc), | 94       new TypeTranspiler(this, this.fc), | 
| 95     ]; | 95     ]; | 
| 96   } | 96   } | 
| 97 | 97 | 
| 98   /** | 98   /** | 
| 99    * Transpiles the given files to Dart. | 99    * Transpiles the given files to Dart. | 
| 100    * @param fileNames The input files. | 100    * @param fileNames The input files. | 
| 101    * @param destination Location to write files to. Creates files next to their 
     sources if absent. | 101    * @param destination Location to write files to. Creates files next to their 
     sources if absent. | 
| 102    */ | 102    */ | 
| 103   transpile(fileNames: string[], destination?: string): void { | 103   transpile(fileNames: string[], destination?: string): void { | 
| 104     if (this.options.basePath) { | 104     if (this.options.basePath) { | 
| 105       this.options.basePath = this.normalizeSlashes(path.resolve(this.options.ba
     sePath)); | 105       this.options.basePath = this.normalizeSlashes(path.resolve(this.options.ba
     sePath)); | 
| 106     } | 106     } | 
| 107     fileNames = fileNames.map((f) => this.normalizeSlashes(f)); | 107     fileNames = fileNames.map((f) => this.normalizeSlashes(f)); | 
| 108     let host = this.createCompilerHost(); | 108     let host = this.createCompilerHost(); | 
| 109     if (this.options.basePath && destination === undefined) { |  | 
| 110       throw new Error( |  | 
| 111           'Must have a destination path when a basePath is specified ' + this.op
     tions.basePath); |  | 
| 112     } |  | 
| 113     let destinationRoot = destination || this.options.basePath || ''; |  | 
| 114     let program = ts.createProgram(fileNames, this.getCompilerOptions(), host); | 109     let program = ts.createProgram(fileNames, this.getCompilerOptions(), host); | 
| 115     this.fc.setTypeChecker(program.getTypeChecker()); | 110     this.fc.setTypeChecker(program.getTypeChecker()); | 
| 116     this.declarationTranspiler.setTypeChecker(program.getTypeChecker()); | 111     this.declarationTranspiler.setTypeChecker(program.getTypeChecker()); | 
| 117 | 112 | 
| 118     // Only write files that were explicitly passed in. | 113     // Only write files that were explicitly passed in. | 
| 119     let fileSet: {[s: string]: boolean} = {}; | 114     let fileSet: {[s: string]: boolean} = {}; | 
| 120     fileNames.forEach((f) => fileSet[f] = true); | 115     fileNames.forEach((f) => fileSet[f] = true); | 
| 121     let sourceFiles = program.getSourceFiles().filter((sourceFile) => fileSet[so
     urceFile.fileName]); | 116     let sourceFiles = program.getSourceFiles().filter((sourceFile) => fileSet[so
     urceFile.fileName]); | 
| 122 | 117 | 
| 123     this.errors = []; | 118     this.errors = []; | 
| 124 | 119 | 
|  | 120     let sourceFileMap: {[s: string]: ts.SourceFile} = {}; | 
|  | 121     sourceFiles.forEach((f: ts.SourceFile) => { sourceFileMap[f.fileName] = f; }
     ); | 
|  | 122 | 
|  | 123     // Check for global module export declarations and propogate them to | 
|  | 124     // and propogate | 
|  | 125     sourceFiles.forEach((f: ts.SourceFile) => { | 
|  | 126       f.statements.forEach((n: ts.Node) => { | 
|  | 127         if (n.kind !== ts.SyntaxKind.GlobalModuleExportDeclaration) return; | 
|  | 128         // This is the name we are interested in for Dart purposes until Dart su
     pports AMD module | 
|  | 129         // loaders. This module name should all be reflected by all modules expo
     rted by this | 
|  | 130         // library as we need to specify a global module location for every Dart
      library. | 
|  | 131         let globalModuleName = base.ident((n as ts.GlobalModuleExportDeclaration
     ).name); | 
|  | 132         f.moduleName = globalModuleName; | 
|  | 133 | 
|  | 134         f.statements.forEach((e: ts.Node) => { | 
|  | 135           if (e.kind !== ts.SyntaxKind.ExportDeclaration) return; | 
|  | 136           let exportDecl = e as ts.ExportDeclaration; | 
|  | 137           if (!exportDecl.moduleSpecifier) return; | 
|  | 138           let moduleLocation = <ts.StringLiteral>exportDecl.moduleSpecifier; | 
|  | 139           let location = moduleLocation.text; | 
|  | 140           let resolvedPath = host.resolveModuleNames([location], f.fileName); | 
|  | 141           resolvedPath.forEach((p) => { | 
|  | 142             if (p.isExternalLibraryImport) return; | 
|  | 143             let exportedFile = sourceFileMap[p.resolvedFileName]; | 
|  | 144             exportedFile.moduleName = globalModuleName; | 
|  | 145           }); | 
|  | 146         }); | 
|  | 147       }); | 
|  | 148     }); | 
|  | 149 | 
| 125     sourceFiles.forEach((f: ts.SourceFile) => { | 150     sourceFiles.forEach((f: ts.SourceFile) => { | 
| 126       let dartCode = this.translate(f); | 151       let dartCode = this.translate(f); | 
| 127       let outputFile = this.getOutputPath(path.resolve(f.fileName), destinationR
     oot); | 152 | 
| 128       mkdirP(path.dirname(outputFile)); | 153       if (destination) { | 
| 129       fs.writeFileSync(outputFile, dartCode); | 154         let outputFile = this.getOutputPath(path.resolve(f.fileName), destinatio
     n); | 
|  | 155         console.log('Output file:', outputFile); | 
|  | 156         mkdirP(path.dirname(outputFile)); | 
|  | 157         fs.writeFileSync(outputFile, dartCode); | 
|  | 158       } else { | 
|  | 159         console.log(dartCode); | 
|  | 160       } | 
| 130     }); | 161     }); | 
| 131     this.checkForErrors(program); | 162     this.checkForErrors(program); | 
| 132   } | 163   } | 
| 133 | 164 | 
| 134   translateProgram(program: ts.Program): {[path: string]: string} { | 165   translateProgram(program: ts.Program): {[path: string]: string} { | 
| 135     this.fc.setTypeChecker(program.getTypeChecker()); | 166     this.fc.setTypeChecker(program.getTypeChecker()); | 
| 136     this.declarationTranspiler.setTypeChecker(program.getTypeChecker()); | 167     this.declarationTranspiler.setTypeChecker(program.getTypeChecker()); | 
| 137 | 168 | 
| 138     let paths: {[path: string]: string} = {}; | 169     let paths: {[path: string]: string} = {}; | 
| 139     this.errors = []; | 170     this.errors = []; | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 174       getCanonicalFileName: (filename) => filename, | 205       getCanonicalFileName: (filename) => filename, | 
| 175       getCurrentDirectory: () => '', | 206       getCurrentDirectory: () => '', | 
| 176       getNewLine: () => '\n', | 207       getNewLine: () => '\n', | 
| 177     }; | 208     }; | 
| 178     compilerHost.resolveModuleNames = getModuleResolver(compilerHost); | 209     compilerHost.resolveModuleNames = getModuleResolver(compilerHost); | 
| 179     return compilerHost; | 210     return compilerHost; | 
| 180   } | 211   } | 
| 181 | 212 | 
| 182   // Visible for testing. | 213   // Visible for testing. | 
| 183   getOutputPath(filePath: string, destinationRoot: string): string { | 214   getOutputPath(filePath: string, destinationRoot: string): string { | 
| 184     let relative = this.getRelativeFileName(filePath); | 215     let relative = this.getDartFileName(filePath); | 
| 185     let dartFile = relative.replace(/.(js|es6|d\.ts|ts)$/, '.dart'); | 216     return this.normalizeSlashes(path.join(destinationRoot, relative)); | 
| 186     return this.normalizeSlashes(path.join(destinationRoot, dartFile)); |  | 
| 187   } | 217   } | 
| 188 | 218 | 
| 189   public pushContext(context: OutputContext) { this.outputStack.push(this.output
     s[context]); } | 219   public pushContext(context: OutputContext) { this.outputStack.push(this.output
     s[context]); } | 
| 190 | 220 | 
| 191   public popContext() { | 221   public popContext() { | 
| 192     if (this.outputStack.length === 0) { | 222     if (this.outputStack.length === 0) { | 
| 193       this.reportError(null, 'Attempting to pop output stack when already empty'
     ); | 223       this.reportError(null, 'Attempting to pop output stack when already empty'
     ); | 
| 194     } | 224     } | 
| 195     this.outputStack.pop(); | 225     this.outputStack.pop(); | 
| 196   } | 226   } | 
| 197 | 227 | 
| 198   private translate(sourceFile: ts.SourceFile): string { | 228   private translate(sourceFile: ts.SourceFile): string { | 
| 199     this.currentFile = sourceFile; | 229     this.currentFile = sourceFile; | 
| 200     this.outputs = []; | 230     this.outputs = []; | 
| 201     this.outputStack = []; | 231     this.outputStack = []; | 
| 202     this.importsEmitted = {}; | 232     this.importsEmitted = {}; | 
| 203     for (let i = 0; i < NUM_OUTPUT_CONTEXTS; ++i) { | 233     for (let i = 0; i < NUM_OUTPUT_CONTEXTS; ++i) { | 
| 204       this.outputs.push(new Output()); | 234       this.outputs.push(new Output()); | 
| 205     } | 235     } | 
| 206 | 236 | 
| 207     this.lastCommentIdx = -1; | 237     this.lastCommentIdx = -1; | 
| 208     merge.normalizeSourceFile(sourceFile); | 238     merge.normalizeSourceFile(sourceFile, this.fc); | 
| 209     this.pushContext(OutputContext.Default); | 239     this.pushContext(OutputContext.Default); | 
| 210     this.visit(sourceFile); | 240     this.visit(sourceFile); | 
| 211     this.popContext(); | 241     this.popContext(); | 
| 212     if (this.outputStack.length > 0) { | 242     if (this.outputStack.length > 0) { | 
| 213       this.reportError( | 243       this.reportError( | 
| 214           sourceFile, 'Internal error managing output contexts. ' + | 244           sourceFile, 'Internal error managing output contexts. ' + | 
| 215               'Inconsistent push and pop context calls.'); | 245               'Inconsistent push and pop context calls.'); | 
| 216     } | 246     } | 
| 217     let result = ''; | 247     let result = ''; | 
| 218     for (let output of this.outputs) { | 248     for (let output of this.outputs) { | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 260       let e = new Error(errors.join('\n')); | 290       let e = new Error(errors.join('\n')); | 
| 261       e.name = 'DartFacadeError'; | 291       e.name = 'DartFacadeError'; | 
| 262       throw e; | 292       throw e; | 
| 263     } | 293     } | 
| 264   } | 294   } | 
| 265 | 295 | 
| 266   /** | 296   /** | 
| 267    * Returns `filePath`, relativized to the program's `basePath`. | 297    * Returns `filePath`, relativized to the program's `basePath`. | 
| 268    * @param filePath Optional path to relativize, defaults to the current file's
      path. | 298    * @param filePath Optional path to relativize, defaults to the current file's
      path. | 
| 269    */ | 299    */ | 
| 270   getRelativeFileName(filePath?: string) { | 300   getRelativeFileName(filePath?: string): string { | 
| 271     if (filePath === undefined) filePath = path.resolve(this.currentFile.fileNam
     e); | 301     if (filePath === undefined) filePath = path.resolve(this.currentFile.fileNam
     e); | 
| 272     // TODO(martinprobst): Use path.isAbsolute on node v0.12. | 302     // TODO(jacobr): Use path.isAbsolute on node v0.12. | 
| 273     if (this.normalizeSlashes(path.resolve('/x/', filePath)) !== filePath) { | 303     if (this.normalizeSlashes(path.resolve('/x/', filePath)) !== filePath) { | 
| 274       return filePath;  // already relative. | 304       return filePath;  // already relative. | 
| 275     } | 305     } | 
| 276     let base = this.options.basePath || ''; | 306     let base = this.options.basePath || ''; | 
| 277     if (filePath.indexOf(base) !== 0 && !filePath.match(/\.d\.ts$/)) { | 307     if (filePath.indexOf(base) !== 0 && !filePath.match(/\.d\.ts$/)) { | 
| 278       throw new Error(`Files must be located under base, got ${filePath} vs ${ba
     se}`); | 308       throw new Error(`Files must be located under base, got ${filePath} vs ${ba
     se}`); | 
| 279     } | 309     } | 
| 280     return this.normalizeSlashes(path.relative(base, filePath)); | 310     return this.normalizeSlashes(path.relative(base, filePath)); | 
| 281   } | 311   } | 
| 282 | 312 | 
|  | 313   getDartFileName(filePath?: string): string { | 
|  | 314     if (filePath === undefined) filePath = path.resolve(this.currentFile.fileNam
     e); | 
|  | 315     filePath = this.normalizeSlashes(filePath); | 
|  | 316     filePath = filePath.replace(/\.(js|es6|d\.ts|ts)$/, '.dart'); | 
|  | 317     // Normalize from node module file path pattern to | 
|  | 318     filePath = filePath.replace(/([^/]+)\/index.dart$/, '$1.dart'); | 
|  | 319     return this.getRelativeFileName(filePath); | 
|  | 320   } | 
|  | 321 | 
|  | 322   isJsModuleFile(): boolean { | 
|  | 323     // Treat files as being part of js modules if they match the node module fil
     e location | 
|  | 324     // convention of module_name/index.js. | 
|  | 325     return !('/' + this.currentFile.fileName).match(/\/index\.(js|es6|d\.ts|ts)$
     /); | 
|  | 326   } | 
|  | 327 | 
| 283   private get currentOutput(): Output { return this.outputStack[this.outputStack
     .length - 1]; } | 328   private get currentOutput(): Output { return this.outputStack[this.outputStack
     .length - 1]; } | 
| 284 | 329 | 
| 285   emit(s: string) { this.currentOutput.emit(s); } | 330   emit(s: string) { this.currentOutput.emit(s); } | 
| 286   emitNoSpace(s: string) { this.currentOutput.emitNoSpace(s); } | 331   emitNoSpace(s: string) { this.currentOutput.emitNoSpace(s); } | 
| 287   maybeLineBreak() { return this.currentOutput.maybeLineBreak(); } | 332   maybeLineBreak() { return this.currentOutput.maybeLineBreak(); } | 
| 288   enterCodeComment() { return this.currentOutput.enterCodeComment(); } | 333   enterCodeComment() { return this.currentOutput.enterCodeComment(); } | 
| 289   exitCodeComment() { return this.currentOutput.exitCodeComment(); } | 334   exitCodeComment() { return this.currentOutput.exitCodeComment(); } | 
|  | 335 | 
|  | 336   enterTypeArgument() { this.typeArgumentDepth++; } | 
|  | 337   exitTypeArgument() { this.typeArgumentDepth--; } | 
|  | 338   get insideTypeArgument(): boolean { return this.typeArgumentDepth > 0; } | 
|  | 339 | 
| 290   emitType(s: string, comment: string) { return this.currentOutput.emitType(s, c
     omment); } | 340   emitType(s: string, comment: string) { return this.currentOutput.emitType(s, c
     omment); } | 
| 291   get insideCodeComment() { return this.currentOutput.insideCodeComment; } | 341   get insideCodeComment() { return this.currentOutput.insideCodeComment; } | 
| 292 | 342 | 
| 293   reportError(n: ts.Node, message: string) { | 343   reportError(n: ts.Node, message: string) { | 
| 294     let file = n.getSourceFile() || this.currentFile; | 344     let file = n.getSourceFile() || this.currentFile; | 
| 295     let fileName = this.getRelativeFileName(file.fileName); | 345     let fileName = this.getRelativeFileName(file.fileName); | 
| 296     let start = n.getStart(file); | 346     let start = n.getStart(file); | 
| 297     let pos = file.getLineAndCharacterOfPosition(start); | 347     let pos = file.getLineAndCharacterOfPosition(start); | 
| 298     // Line and character are 0-based. | 348     // Line and character are 0-based. | 
| 299     let fullMessage = `${fileName}:${pos.line + 1}:${pos.character + 1}: ${messa
     ge}`; | 349     let fullMessage = `${fileName}:${pos.line + 1}:${pos.character + 1}: ${messa
     ge}`; | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 404       // Avoid line breaks inside code comments. | 454       // Avoid line breaks inside code comments. | 
| 405       return; | 455       return; | 
| 406     } | 456     } | 
| 407 | 457 | 
| 408     if (!this.firstColumn) { | 458     if (!this.firstColumn) { | 
| 409       this.emitNoSpace('\n'); | 459       this.emitNoSpace('\n'); | 
| 410     } | 460     } | 
| 411   } | 461   } | 
| 412 | 462 | 
| 413   emit(str: string) { | 463   emit(str: string) { | 
| 414     if (this.result.length > 0) { | 464     let buffer = this.insideCodeComment ? this.codeCommentResult : this.result; | 
| 415       let buffer = this.insideCodeComment ? this.codeCommentResult : this.result
     ; | 465     if (buffer.length > 0) { | 
| 416       let lastChar = buffer[buffer.length - 1]; | 466       let lastChar = buffer.slice(-1); | 
| 417       if (lastChar !== ' ' && lastChar !== '(' && lastChar !== '<' && lastChar !
     == '[') { | 467       if (lastChar !== ' ' && lastChar !== '(' && lastChar !== '<' && lastChar !
     == '[') { | 
| 418         // Avoid emitting a space in obvious cases where a space is not required | 468         // Avoid emitting a space in obvious cases where a space is not required | 
| 419         // to make the output slightly prettier in cases where the DartFormatter | 469         // to make the output slightly prettier in cases where the DartFormatter | 
| 420         // cannot run such as within a comment where code we emit is not quite | 470         // cannot run such as within a comment where code we emit is not quite | 
| 421         // valid Dart code. | 471         // valid Dart code. | 
| 422         this.emitNoSpace(' '); | 472         this.emitNoSpace(' '); | 
| 423       } | 473       } | 
| 424     } | 474     } | 
| 425     this.emitNoSpace(str); | 475     this.emitNoSpace(str); | 
| 426   } | 476   } | 
| 427 | 477 | 
| 428   emitNoSpace(str: string) { | 478   emitNoSpace(str: string) { | 
| 429     if (str.length === 0) return; | 479     if (str.length === 0) return; | 
| 430     if (this.insideCodeComment) { | 480     if (this.insideCodeComment) { | 
| 431       this.codeCommentResult += str; | 481       this.codeCommentResult += str; | 
| 432       return; | 482       return; | 
| 433     } | 483     } | 
| 434     this.result += str; | 484     this.result += str; | 
| 435     this.firstColumn = str[str.length - 1] === '\n'; | 485     this.firstColumn = str.slice(-1) === '\n'; | 
| 436   } | 486   } | 
| 437 | 487 | 
| 438   enterCodeComment() { | 488   enterCodeComment() { | 
| 439     if (this.insideCodeComment) { | 489     if (this.insideCodeComment) { | 
| 440       throw 'Cannot nest code comments' + this.codeCommentResult; | 490       throw 'Cannot nest code comments' + this.codeCommentResult; | 
| 441     } | 491     } | 
| 442     this.insideCodeComment = true; | 492     this.insideCodeComment = true; | 
| 443     this.codeCommentResult = ''; | 493     this.codeCommentResult = ''; | 
| 444   } | 494   } | 
| 445 | 495 | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 494   try { | 544   try { | 
| 495     let transpiler = new Transpiler(args); | 545     let transpiler = new Transpiler(args); | 
| 496     console.error('Transpiling', args._, 'to', args.destination); | 546     console.error('Transpiling', args._, 'to', args.destination); | 
| 497     transpiler.transpile(args._, args.destination); | 547     transpiler.transpile(args._, args.destination); | 
| 498   } catch (e) { | 548   } catch (e) { | 
| 499     if (e.name !== 'DartFacadeError') throw e; | 549     if (e.name !== 'DartFacadeError') throw e; | 
| 500     console.error(e.message); | 550     console.error(e.message); | 
| 501     process.exit(1); | 551     process.exit(1); | 
| 502   } | 552   } | 
| 503 } | 553 } | 
| OLD | NEW | 
|---|