| OLD | NEW | 
|---|
| 1 import * as ts from 'typescript'; | 1 import * as ts from 'typescript'; | 
| 2 | 2 | 
| 3 import * as base from './base'; | 3 import * as base from './base'; | 
| 4 import {FacadeConverter} from './facade_converter'; | 4 import {FacadeConverter} from './facade_converter'; | 
| 5 import {Transpiler} from './main'; | 5 import {Transpiler} from './main'; | 
| 6 import {MergedParameter, MergedType} from './merge'; | 6 import {MergedParameter, MergedType, MergedTypeParameters} from './merge'; | 
| 7 | 7 | 
| 8 export function isFunctionLikeProperty( | 8 export function isFunctionLikeProperty( | 
| 9     decl: ts.PropertyDeclaration|ts.ParameterDeclaration, tc: ts.TypeChecker): b
     oolean { | 9     decl: ts.PropertyDeclaration|ts.ParameterDeclaration, tc: ts.TypeChecker): b
     oolean { | 
| 10   if (!decl.type) return false; | 10   if (!decl.type) return false; | 
|  | 11   if (decl.name.kind !== ts.SyntaxKind.Identifier) { | 
|  | 12     // No need to promote properties | 
|  | 13     return false; | 
|  | 14   } | 
| 11   let name = base.ident(decl.name); | 15   let name = base.ident(decl.name); | 
| 12   if (name.match(/^on[A-Z]/)) return false; | 16   if (name.match(/^on[A-Z]/)) return false; | 
| 13   return base.isFunctionType(decl.type, tc); | 17   return base.isFunctionType(decl.type, tc); | 
| 14 } | 18 } | 
| 15 | 19 | 
| 16 export default class DeclarationTranspiler extends base.TranspilerBase { | 20 export default class DeclarationTranspiler extends base.TranspilerBase { | 
| 17   private tc: ts.TypeChecker; | 21   private tc: ts.TypeChecker; | 
| 18 | 22 | 
| 19   private moduleStack: string[] = []; |  | 
| 20   private extendsClass: boolean = false; | 23   private extendsClass: boolean = false; | 
| 21 | 24 | 
| 22   static NUM_FAKE_REST_PARAMETERS = 5; | 25   static NUM_FAKE_REST_PARAMETERS = 5; | 
| 23 | 26 | 
| 24   setTypeChecker(tc: ts.TypeChecker) { this.tc = tc; } | 27   setTypeChecker(tc: ts.TypeChecker) { this.tc = tc; } | 
| 25   setFacadeConverter(fc: FacadeConverter) { this.fc = fc; } | 28   setFacadeConverter(fc: FacadeConverter) { this.fc = fc; } | 
| 26 | 29 | 
| 27   getJsPath(node: ts.Node): string { | 30   getJsPath(node: ts.Node, suppressUnneededPaths = true): string { | 
| 28     let path = [].concat(this.moduleStack); | 31     let path: Array<String> = []; | 
|  | 32     let moduleDecl = | 
|  | 33         base.getAncestor(node, ts.SyntaxKind.ModuleDeclaration) as ts.ModuleDecl
     aration; | 
|  | 34     while (moduleDecl != null) { | 
|  | 35       path.unshift(moduleDecl.name.text); | 
|  | 36       moduleDecl = | 
|  | 37           base.getAncestor( | 
|  | 38                   moduleDecl.parent, ts.SyntaxKind.ModuleDeclaration) as ts.Modu
     leDeclaration; | 
|  | 39     } | 
|  | 40 | 
| 29     let classDecl = base.getEnclosingClass(node); | 41     let classDecl = base.getEnclosingClass(node); | 
| 30     if (classDecl) { | 42     if (classDecl) { | 
| 31       path.push(classDecl.name.text); | 43       if (classDecl.kind === ts.SyntaxKind.InterfaceDeclaration) { | 
|  | 44         let interfaceDecl = classDecl as base.ExtendedInterfaceDeclaration; | 
|  | 45         if (interfaceDecl.classLikeVariableDeclaration) { | 
|  | 46           // We upgrade these variable interface declarations to behave more | 
|  | 47           // like class declarations as we have a valid concrete JS class to | 
|  | 48           // an appropriate class object. | 
|  | 49           return this.getJsPath(interfaceDecl.classLikeVariableDeclaration, fals
     e); | 
|  | 50         } | 
|  | 51         return ''; | 
|  | 52       } else { | 
|  | 53         path.push(classDecl.name.text); | 
|  | 54       } | 
| 32     } | 55     } | 
| 33 | 56 | 
| 34     switch (node.kind) { | 57     switch (node.kind) { | 
| 35       case ts.SyntaxKind.ModuleDeclaration: | 58       case ts.SyntaxKind.ModuleDeclaration: | 
|  | 59         path.push((<ts.ModuleDeclaration>node).name.text); | 
| 36         break; | 60         break; | 
| 37       case ts.SyntaxKind.ClassDeclaration: | 61       case ts.SyntaxKind.ClassDeclaration: | 
| 38       case ts.SyntaxKind.InterfaceDeclaration: | 62       case ts.SyntaxKind.InterfaceDeclaration: | 
| 39         path.push((<base.ClassLike>node).name.text); | 63         // Already handled by call to getEnclosingClass. | 
| 40         break; | 64         break; | 
| 41       case ts.SyntaxKind.EnumDeclaration: | 65       case ts.SyntaxKind.EnumDeclaration: | 
| 42         path.push((<ts.EnumDeclaration>node).name.text); | 66         path.push((<ts.EnumDeclaration>node).name.text); | 
| 43         break; | 67         break; | 
| 44       case ts.SyntaxKind.PropertyDeclaration: | 68       case ts.SyntaxKind.PropertyDeclaration: | 
| 45       case ts.SyntaxKind.VariableDeclaration: | 69       case ts.SyntaxKind.VariableDeclaration: | 
| 46       case ts.SyntaxKind.MethodDeclaration: | 70       case ts.SyntaxKind.MethodDeclaration: | 
|  | 71       case ts.SyntaxKind.MethodSignature: | 
| 47       case ts.SyntaxKind.FunctionDeclaration: | 72       case ts.SyntaxKind.FunctionDeclaration: | 
| 48       case ts.SyntaxKind.GetAccessor: | 73       case ts.SyntaxKind.GetAccessor: | 
| 49       case ts.SyntaxKind.SetAccessor: | 74       case ts.SyntaxKind.SetAccessor: | 
| 50       case ts.SyntaxKind.PropertySignature: | 75       case ts.SyntaxKind.PropertySignature: | 
| 51         let memberName = base.ident((<base.NamedDeclaration>node).name); | 76         let memberName = base.ident((<base.NamedDeclaration>node).name); | 
| 52         if (!base.isStatic(node) && classDecl != null) return memberName; | 77         if (!base.isStatic(node) && classDecl != null) return memberName; | 
| 53         path.push(memberName); | 78         path.push(memberName); | 
| 54         break; | 79         break; | 
| 55       default: | 80       default: | 
| 56         throw 'Internal error. Unexpected node kind:' + node.kind; | 81         throw 'Internal error. Unexpected node kind:' + node.kind; | 
| 57     } | 82     } | 
| 58     if (path.length === 1) { | 83     if (suppressUnneededPaths && path.length === 1) { | 
| 59       // No need to specify the path if is simply the node name. | 84       // No need to specify the path if is simply the node name or the escaped v
     ersion of the node | 
|  | 85       // name. | 
| 60       return ''; | 86       return ''; | 
| 61     } | 87     } | 
| 62     return path.join('.'); | 88     return path.join('.'); | 
| 63   } | 89   } | 
| 64 | 90 | 
| 65   private isAnonymousInterface(node: ts.Node): boolean { | 91   private isAnonymousInterface(node: ts.Node): boolean { | 
| 66     if (node.kind !== ts.SyntaxKind.InterfaceDeclaration) return false; | 92     if (node.kind !== ts.SyntaxKind.InterfaceDeclaration) return false; | 
| 67     // This is a bit of a hack but for the purposes of Dart codegen, | 93     let interfaceDecl = node as base.ExtendedInterfaceDeclaration; | 
| 68     // interfaces with static members or constructors have a known class name | 94     // If we were able to associate a variable declaration with the interface de
     finition then | 
| 69     // at least for the purposes of resolving static members. | 95     // the interface isn't actually anonymous. | 
| 70     // Example case that triggers this case: | 96     return !interfaceDecl.classLikeVariableDeclaration; | 
| 71     // interface Foo { |  | 
| 72     //   bar(); |  | 
| 73     // } |  | 
| 74     // declare let Foo: { |  | 
| 75     //   new(): Foo, |  | 
| 76     //   SOME_STATIC : number; |  | 
| 77     // } |  | 
| 78     return (<ts.InterfaceDeclaration>node).members.every((m: ts.Declaration) => 
     { |  | 
| 79       return m.kind !== ts.SyntaxKind.Constructor && !base.isStatic(m); |  | 
| 80     }); |  | 
| 81   } | 97   } | 
| 82 | 98 | 
| 83   maybeEmitJsAnnotation(node: ts.Node) { | 99   maybeEmitJsAnnotation(node: ts.Node) { | 
| 84     // No need to emit the annotations as an entity outside the code comment | 100     // No need to emit the annotations as an entity outside the code comment | 
| 85     // will already have the same annotation. | 101     // will already have the same annotation. | 
| 86     if (this.insideCodeComment) return; | 102     if (this.insideCodeComment) return; | 
| 87 | 103 | 
| 88     if (this.isAnonymousInterface(node)) { | 104     if (this.isAnonymousInterface(node)) { | 
| 89       this.emit('@anonymous'); | 105       this.emit('@anonymous'); | 
| 90       this.emit('@JS()'); | 106       this.emit('@JS()'); | 
| 91       return; | 107       return; | 
| 92     } | 108     } | 
| 93     let name: String = this.getJsPath(node); | 109     let name: String = this.getJsPath(node); | 
| 94     this.emit('@JS('); | 110     this.emit('@JS('); | 
| 95     if (name.length > 0) { | 111     if (name.length > 0) { | 
| 96       this.emit('"' + name + '"'); | 112       this.emit('"' + name + '"'); | 
| 97     } | 113     } | 
| 98     this.emit(')'); | 114     this.emit(')'); | 
| 99   } | 115   } | 
| 100 | 116 | 
| 101   /** | 117   /** | 
| 102    * Emit fake constructors to placate the Dart Analyzer for JS Interop classes. | 118    * Emit fake constructors to placate the Dart Analyzer for JS Interop classes. | 
| 103    */ | 119    */ | 
| 104   maybeEmitFakeConstructors(decl: base.ClassLike) { | 120   maybeEmitFakeConstructors(decl: ts.Node) { | 
| 105     if (decl.kind === ts.SyntaxKind.ClassDeclaration) { | 121     if (decl.kind === ts.SyntaxKind.ClassDeclaration) { | 
| 106       // Required to avoid spurious dart errors involving base classes without | 122       // Required to avoid spurious dart errors involving base classes without | 
| 107       // default constructors. | 123       // default constructors. | 
| 108       this.emit('// @Ignore\n'); | 124       this.emit('// @Ignore\n'); | 
| 109       this.fc.visitTypeName(decl.name); | 125       this.fc.visitTypeName((<ts.ClassDeclaration>decl).name); | 
| 110       this.emit('.fakeConstructor$()'); | 126       this.emit('.fakeConstructor$()'); | 
| 111       if (this.extendsClass) { | 127       if (this.extendsClass) { | 
| 112         // Required to keep the Dart Analyzer happy when a class has subclasses. | 128         // Required to keep the Dart Analyzer happy when a class has subclasses. | 
| 113         this.emit(': super.fakeConstructor$()'); | 129         this.emit(': super.fakeConstructor$()'); | 
| 114       } | 130       } | 
| 115       this.emit(';\n'); | 131       this.emit(';\n'); | 
| 116     } | 132     } | 
| 117   } | 133   } | 
| 118 | 134 | 
| 119   private visitName(name: ts.Node) { | 135   private visitName(name: ts.Node) { | 
| 120     if (base.getEnclosingClass(name) != null) { | 136     if (base.getEnclosingClass(name) != null) { | 
| 121       this.visit(name); | 137       this.visit(name); | 
| 122       return; | 138       return; | 
| 123     } | 139     } | 
| 124     // Have to rewrite names in this case as we could have conflicts | 140     // Have to rewrite names in this case as we could have conflicts | 
| 125     // due to needing to support multiple JS modules in a single JS module | 141     // due to needing to support multiple JS modules in a single JS module | 
| 126     if (name.kind !== ts.SyntaxKind.Identifier) { | 142     if (name.kind !== ts.SyntaxKind.Identifier) { | 
| 127       throw 'Internal error: unexpected function name kind:' + name.kind; | 143       throw 'Internal error: unexpected function name kind:' + name.kind; | 
| 128     } | 144     } | 
| 129     let entry = this.fc.lookupCustomDartTypeName(<ts.Identifier>name, this.insid
     eCodeComment); | 145     let entry = this.fc.lookupCustomDartTypeName(<ts.Identifier>name); | 
| 130     if (entry) { | 146     if (entry) { | 
| 131       this.emit(entry.name); | 147       this.emit(entry.name); | 
| 132       return; | 148       return; | 
| 133     } | 149     } | 
| 134 | 150 | 
| 135     this.visit(name); | 151     this.visit(name); | 
| 136   } | 152   } | 
| 137 | 153 | 
| 138   private notSimpleBagOfProperties(type: ts.Type): boolean { | 154   private notSimpleBagOfProperties(type: ts.Type): boolean { | 
| 139     if (this.tc.getSignaturesOfType(type, ts.SignatureKind.Call).length > 0) ret
     urn true; | 155     if (this.tc.getSignaturesOfType(type, ts.SignatureKind.Call).length > 0) ret
     urn true; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 160     return false; | 176     return false; | 
| 161   } | 177   } | 
| 162 | 178 | 
| 163   /** | 179   /** | 
| 164    * Returns whether all members of the class and all base classes | 180    * Returns whether all members of the class and all base classes | 
| 165    */ | 181    */ | 
| 166   hasOnlyProperties(decl: ts.InterfaceDeclaration, outProperties: ts.PropertyDec
     laration[]): | 182   hasOnlyProperties(decl: ts.InterfaceDeclaration, outProperties: ts.PropertyDec
     laration[]): | 
| 167       boolean { | 183       boolean { | 
| 168     let type = <ts.InterfaceType>this.tc.getTypeAtLocation(decl); | 184     let type = <ts.InterfaceType>this.tc.getTypeAtLocation(decl); | 
| 169 | 185 | 
| 170     let properties = this.tc.getPropertiesOfType(type); | 186     let symbols = this.tc.getPropertiesOfType(type); | 
| 171     let baseTypes = this.tc.getBaseTypes(type); | 187     let baseTypes = this.tc.getBaseTypes(type); | 
| 172     if (this.notSimpleBagOfProperties(type)) return false; | 188     if (this.notSimpleBagOfProperties(type)) return false; | 
| 173     for (let i = 0; i < baseTypes.length; ++i) { | 189     for (let i = 0; i < baseTypes.length; ++i) { | 
| 174       let baseType = baseTypes[i]; | 190       let baseType = baseTypes[i]; | 
| 175       if (this.notSimpleBagOfProperties(baseType)) return false; | 191       if (this.notSimpleBagOfProperties(baseType)) return false; | 
| 176     } | 192     } | 
| 177 | 193 | 
|  | 194     let properties: ts.Declaration[] = []; | 
|  | 195 | 
|  | 196     for (let i = 0; i < symbols.length; ++i) { | 
|  | 197       let symbol = symbols[i]; | 
|  | 198       let property = symbol.valueDeclaration; | 
|  | 199       properties.push(property); | 
|  | 200     } | 
|  | 201     return this.hasOnlyPropertiesHelper(properties, outProperties); | 
|  | 202   } | 
|  | 203 | 
|  | 204   hasOnlyPropertiesHelper(properties: ts.Declaration[], outProperties: ts.Declar
     ation[]): boolean { | 
| 178     for (let i = 0; i < properties.length; ++i) { | 205     for (let i = 0; i < properties.length; ++i) { | 
| 179       let symbol = properties[i]; | 206       let node = properties[i]; | 
| 180       let node = symbol.valueDeclaration; |  | 
| 181       switch (node.kind) { | 207       switch (node.kind) { | 
| 182         case ts.SyntaxKind.PropertyDeclaration: | 208         case ts.SyntaxKind.PropertyDeclaration: | 
| 183         case ts.SyntaxKind.PropertySignature: | 209         case ts.SyntaxKind.PropertySignature: | 
| 184         case ts.SyntaxKind.VariableDeclaration: | 210         case ts.SyntaxKind.VariableDeclaration: | 
| 185           let prop = <ts.PropertyDeclaration>node; | 211           let prop = <ts.PropertyDeclaration>node; | 
| 186           if (this.promoteFunctionLikeMembers && isFunctionLikeProperty(prop, th
     is.tc)) { | 212           if (this.promoteFunctionLikeMembers && isFunctionLikeProperty(prop, th
     is.tc)) { | 
| 187             return false; | 213             return false; | 
| 188           } | 214           } | 
| 189           outProperties.push(prop); | 215           outProperties.push(prop); | 
| 190           break; | 216           break; | 
| 191         default: | 217         default: | 
| 192           return false; | 218           return false; | 
| 193       } | 219       } | 
| 194     } | 220     } | 
| 195     return outProperties.length > 0; | 221     return outProperties.length > 0; | 
| 196   } | 222   } | 
| 197 | 223 | 
| 198   visitClassBody(decl: base.ClassLike) { | 224   visitClassBody(decl: base.ClassLike|ts.TypeLiteralNode, name: ts.Identifier) { | 
| 199     let properties: ts.PropertyDeclaration[] = []; | 225     let properties: ts.PropertyDeclaration[] = []; | 
| 200     let isPropertyBag = decl.kind === ts.SyntaxKind.InterfaceDeclaration && | 226     let isPropertyBag = false; | 
| 201         this.hasOnlyProperties(<ts.InterfaceDeclaration>decl, properties); | 227     if (decl.kind === ts.SyntaxKind.InterfaceDeclaration) { | 
|  | 228       isPropertyBag = this.hasOnlyProperties(<ts.InterfaceDeclaration>decl, prop
     erties); | 
|  | 229     } else if (decl.kind === ts.SyntaxKind.TypeLiteral) { | 
|  | 230       isPropertyBag = this.hasOnlyPropertiesHelper(decl.members, properties); | 
|  | 231     } | 
| 202     this.visitMergingOverloads(decl.members); | 232     this.visitMergingOverloads(decl.members); | 
| 203 | 233 | 
| 204     if (isPropertyBag) { | 234     if (isPropertyBag) { | 
| 205       this.emit('external factory'); | 235       this.emit('external factory'); | 
| 206       this.fc.visitTypeName(decl.name); | 236       this.fc.visitTypeName(name); | 
| 207       this.emitNoSpace('({'); | 237       this.emitNoSpace('({'); | 
| 208       for (let i = 0; i < properties.length; i++) { | 238       for (let i = 0; i < properties.length; i++) { | 
| 209         if (i > 0) this.emitNoSpace(','); | 239         if (i > 0) this.emitNoSpace(','); | 
| 210         let p = properties[i]; | 240         let p = properties[i]; | 
| 211         this.visit(p.type); | 241         this.visit(p.type); | 
| 212         this.visit(p.name); | 242         this.visit(p.name); | 
| 213       } | 243       } | 
| 214       this.emitNoSpace('});'); | 244       this.emitNoSpace('});'); | 
| 215     } | 245     } | 
| 216   } | 246   } | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 267         case ts.SyntaxKind.Constructor: | 297         case ts.SyntaxKind.Constructor: | 
| 268           break; | 298           break; | 
| 269         case ts.SyntaxKind.ConstructSignature: | 299         case ts.SyntaxKind.ConstructSignature: | 
| 270           break; | 300           break; | 
| 271         case ts.SyntaxKind.IndexSignature: | 301         case ts.SyntaxKind.IndexSignature: | 
| 272           name = '[]'; | 302           name = '[]'; | 
| 273           break; | 303           break; | 
| 274         case ts.SyntaxKind.ClassDeclaration: | 304         case ts.SyntaxKind.ClassDeclaration: | 
| 275         case ts.SyntaxKind.InterfaceDeclaration: | 305         case ts.SyntaxKind.InterfaceDeclaration: | 
| 276         case ts.SyntaxKind.VariableStatement: | 306         case ts.SyntaxKind.VariableStatement: | 
| 277           orderedGroups.push([node]); |  | 
| 278           return; |  | 
| 279         case ts.SyntaxKind.GetAccessor: | 307         case ts.SyntaxKind.GetAccessor: | 
| 280         case ts.SyntaxKind.SetAccessor: | 308         case ts.SyntaxKind.SetAccessor: | 
| 281         case ts.SyntaxKind.SemicolonClassElement: | 309         case ts.SyntaxKind.SemicolonClassElement: | 
| 282         case ts.SyntaxKind.ModuleDeclaration: | 310         case ts.SyntaxKind.ModuleDeclaration: | 
| 283         case ts.SyntaxKind.TypeAliasDeclaration: | 311         case ts.SyntaxKind.TypeAliasDeclaration: | 
| 284         case ts.SyntaxKind.ExportAssignment: | 312         case ts.SyntaxKind.ExportAssignment: | 
|  | 313         case ts.SyntaxKind.EnumDeclaration: | 
|  | 314         case ts.SyntaxKind.ImportDeclaration: | 
|  | 315         case ts.SyntaxKind.ExportDeclaration: | 
|  | 316         case ts.SyntaxKind.GlobalModuleExportDeclaration: | 
|  | 317         case ts.SyntaxKind.ImportEqualsDeclaration: | 
|  | 318         case ts.SyntaxKind.EmptyStatement: | 
|  | 319         case ts.SyntaxKind.ExpressionStatement: | 
|  | 320           // Types where we don't need to perform any merging overloads work. | 
| 285           orderedGroups.push([node]); | 321           orderedGroups.push([node]); | 
| 286           return; | 322           return; | 
| 287         default: | 323         default: | 
| 288           console.log('Warning: unexpected type... overloads: ' + node.kind + ' 
     ' + node.getText()); | 324           // This warning is to make sure we aren't quietly missing a type we ne
     ed to perform | 
|  | 325           // overload chunking and merging on. | 
|  | 326           console.log( | 
|  | 327               'Warning: unexpected type found looking for overloads: ' + node.ki
     nd + ' ' + | 
|  | 328               node.getText()); | 
| 289           orderedGroups.push([node]); | 329           orderedGroups.push([node]); | 
| 290           return; | 330           return; | 
| 291       } | 331       } | 
| 292       let group: Array<ts.Node>; | 332       let group: Array<ts.Node>; | 
| 293       if (Object.prototype.hasOwnProperty.call(groups, name)) { | 333       if (Object.prototype.hasOwnProperty.call(groups, name)) { | 
| 294         group = groups[name]; | 334         group = groups[name]; | 
| 295       } else { | 335       } else { | 
| 296         group = []; | 336         group = []; | 
| 297         groups[name] = group; | 337         groups[name] = group; | 
| 298         orderedGroups.push(group); | 338         orderedGroups.push(group); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 337         case ts.SyntaxKind.IndexSignature: | 377         case ts.SyntaxKind.IndexSignature: | 
| 338           break; | 378           break; | 
| 339         default: | 379         default: | 
| 340           throw 'Unexpected kind:' + kind; | 380           throw 'Unexpected kind:' + kind; | 
| 341       } | 381       } | 
| 342       let mergedParams = first.parameters.map( | 382       let mergedParams = first.parameters.map( | 
| 343           (param: ts.ParameterDeclaration) => new MergedParameter(param, this.fc
     )); | 383           (param: ts.ParameterDeclaration) => new MergedParameter(param, this.fc
     )); | 
| 344       let mergedType = new MergedType(this.fc); | 384       let mergedType = new MergedType(this.fc); | 
| 345       mergedType.merge(first.type); | 385       mergedType.merge(first.type); | 
| 346 | 386 | 
|  | 387       let mergedTypeParams = new MergedTypeParameters(this.fc); | 
|  | 388       mergedTypeParams.merge(first.typeParameters); | 
|  | 389 | 
| 347       for (let i = 1; i < group.length; ++i) { | 390       for (let i = 1; i < group.length; ++i) { | 
| 348         let signature = <ts.SignatureDeclaration>group[i]; | 391         let signature = <ts.SignatureDeclaration>group[i]; | 
| 349         mergedType.merge(signature.type); | 392         mergedType.merge(signature.type); | 
|  | 393         mergedTypeParams.merge(signature.typeParameters); | 
| 350         let overlap = Math.min(signature.parameters.length, mergedParams.length)
     ; | 394         let overlap = Math.min(signature.parameters.length, mergedParams.length)
     ; | 
| 351         for (let j = 0; j < overlap; ++j) { | 395         for (let j = 0; j < overlap; ++j) { | 
| 352           mergedParams[j].merge(signature.parameters[j]); | 396           mergedParams[j].merge(signature.parameters[j]); | 
| 353         } | 397         } | 
| 354         for (let j = overlap; j < mergedParams.length; ++j) { | 398         for (let j = overlap; j < mergedParams.length; ++j) { | 
| 355           mergedParams[j].setOptional(); | 399           mergedParams[j].setOptional(); | 
| 356         } | 400         } | 
| 357         for (let j = mergedParams.length; j < signature.parameters.length; ++j) 
     { | 401         for (let j = mergedParams.length; j < signature.parameters.length; ++j) 
     { | 
| 358           let param = new MergedParameter(signature.parameters[j], this.fc); | 402           let param = new MergedParameter(signature.parameters[j], this.fc); | 
| 359           param.setOptional(); | 403           param.setOptional(); | 
| 360           mergedParams.push(param); | 404           mergedParams.push(param); | 
| 361         } | 405         } | 
| 362       } | 406       } | 
| 363       merged.parameters = <ts.NodeArray<ts.ParameterDeclaration>>mergedParams.ma
     p( | 407       merged.parameters = <ts.NodeArray<ts.ParameterDeclaration>>mergedParams.ma
     p( | 
| 364           (p) => p.toParameterDeclaration()); | 408           (p) => p.toParameterDeclaration()); | 
| 365       merged.type = mergedType.toTypeNode(); | 409       merged.type = mergedType.toTypeNode(); | 
|  | 410       merged.typeParameters = mergedTypeParams.toTypeParameters(); | 
| 366 | 411 | 
| 367       this.fc.visit(merged); | 412       this.fc.visit(merged); | 
| 368     }); | 413     }); | 
| 369   } | 414   } | 
| 370 | 415 | 
| 371 | 416 | 
| 372   constructor( | 417   constructor( | 
| 373       tr: Transpiler, private fc: FacadeConverter, private enforceUnderscoreConv
     entions: boolean, | 418       tr: Transpiler, private fc: FacadeConverter, private enforceUnderscoreConv
     entions: boolean, | 
| 374       private promoteFunctionLikeMembers: boolean) { | 419       private promoteFunctionLikeMembers: boolean) { | 
| 375     super(tr); | 420     super(tr); | 
| 376   } | 421   } | 
| 377 | 422 | 
| 378   visitNode(node: ts.Node): boolean { | 423   visitNode(node: ts.Node): boolean { | 
| 379     switch (node.kind) { | 424     switch (node.kind) { | 
| 380       case ts.SyntaxKind.ModuleDeclaration: | 425       case ts.SyntaxKind.ModuleDeclaration: | 
| 381         let moduleDecl = <ts.ModuleDeclaration>node; | 426         let moduleDecl = <ts.ModuleDeclaration>node; | 
|  | 427         if (moduleDecl.name.text.slice(0, 2) === '..') { | 
|  | 428           this.emit( | 
|  | 429               '\n// Library augmentation not allowed by Dart. Ignoring augmentat
     ion of ' + | 
|  | 430               moduleDecl.name.text + '\n'); | 
|  | 431           break; | 
|  | 432         } | 
| 382         this.emit('\n// Module ' + moduleDecl.name.text + '\n'); | 433         this.emit('\n// Module ' + moduleDecl.name.text + '\n'); | 
| 383         this.moduleStack.push(moduleDecl.name.text); |  | 
| 384 |  | 
| 385         this.visit(moduleDecl.body); | 434         this.visit(moduleDecl.body); | 
| 386         this.emit('\n// End module ' + moduleDecl.name.text + '\n'); | 435         this.emit('\n// End module ' + moduleDecl.name.text + '\n'); | 
| 387         this.moduleStack.pop(); |  | 
| 388         break; | 436         break; | 
| 389       case ts.SyntaxKind.ExportKeyword: | 437       case ts.SyntaxKind.ExportKeyword: | 
| 390         // TODO(jacobr): perhaps add a specific Dart annotation to indicate | 438         // TODO(jacobr): perhaps add a specific Dart annotation to indicate | 
| 391         // exported members or provide a flag to only generate code for exported | 439         // exported members or provide a flag to only generate code for exported | 
| 392         // members. | 440         // members. | 
| 393         break; | 441         break; | 
| 394       case ts.SyntaxKind.EnumDeclaration: { | 442       case ts.SyntaxKind.EnumDeclaration: { | 
| 395         let decl = <ts.EnumDeclaration>node; | 443         let decl = <ts.EnumDeclaration>node; | 
| 396         // The only legal modifier for an enum decl is const. | 444         // The only legal modifier for an enum decl is const. | 
| 397         let isConst = decl.modifiers && (decl.modifiers.flags & ts.NodeFlags.Con
     st); | 445         let isConst = decl.modifiers && (decl.modifiers.flags & ts.NodeFlags.Con
     st); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 432 | 480 | 
| 433         if (paramDecl.dotDotDotToken) { | 481         if (paramDecl.dotDotDotToken) { | 
| 434           // Weak support of varargs that works ok if you have 5 of fewer args. | 482           // Weak support of varargs that works ok if you have 5 of fewer args. | 
| 435           let paramType: ts.TypeNode; | 483           let paramType: ts.TypeNode; | 
| 436           let type = paramDecl.type; | 484           let type = paramDecl.type; | 
| 437           if (type) { | 485           if (type) { | 
| 438             if (type.kind === ts.SyntaxKind.ArrayType) { | 486             if (type.kind === ts.SyntaxKind.ArrayType) { | 
| 439               let arrayType = <ts.ArrayTypeNode>type; | 487               let arrayType = <ts.ArrayTypeNode>type; | 
| 440               paramType = arrayType.elementType; | 488               paramType = arrayType.elementType; | 
| 441             } else if (type.kind !== ts.SyntaxKind.AnyKeyword) { | 489             } else if (type.kind !== ts.SyntaxKind.AnyKeyword) { | 
| 442               throw 'Unexpected type for varargs: ' + type.kind; | 490               console.log('Warning: falling back to dynamic for varArgs type: ' 
     + type.getText()); | 
| 443             } | 491             } | 
| 444           } | 492           } | 
| 445 | 493 | 
| 446           for (let i = 1; i <= DeclarationTranspiler.NUM_FAKE_REST_PARAMETERS; +
     +i) { | 494           for (let i = 1; i <= DeclarationTranspiler.NUM_FAKE_REST_PARAMETERS; +
     +i) { | 
| 447             if (i > 1) { | 495             if (i > 1) { | 
| 448               this.emitNoSpace(','); | 496               this.emitNoSpace(','); | 
| 449             } | 497             } | 
| 450             this.visit(paramType); | 498             this.visit(paramType); | 
| 451             this.emit(base.ident(paramDecl.name) + i); | 499             this.emit(base.ident(paramDecl.name) + i); | 
| 452           } | 500           } | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 470         if (paramDecl.name.kind !== ts.SyntaxKind.Identifier) { | 518         if (paramDecl.name.kind !== ts.SyntaxKind.Identifier) { | 
| 471           throw 'Unsupported parameter name kind: ' + paramDecl.name.kind; | 519           throw 'Unsupported parameter name kind: ' + paramDecl.name.kind; | 
| 472         } | 520         } | 
| 473         this.visit(paramDecl.type); | 521         this.visit(paramDecl.type); | 
| 474         this.visit(paramDecl.name); | 522         this.visit(paramDecl.name); | 
| 475       } break; | 523       } break; | 
| 476       case ts.SyntaxKind.EnumMember: { | 524       case ts.SyntaxKind.EnumMember: { | 
| 477         let member = <ts.EnumMember>node; | 525         let member = <ts.EnumMember>node; | 
| 478         this.visit(member.name); | 526         this.visit(member.name); | 
| 479       } break; | 527       } break; | 
|  | 528       case ts.SyntaxKind.SourceFile: | 
|  | 529         let sourceFile = node as ts.SourceFile; | 
|  | 530         this.visitMergingOverloads(sourceFile.statements); | 
|  | 531         break; | 
| 480       case ts.SyntaxKind.ModuleBlock: { | 532       case ts.SyntaxKind.ModuleBlock: { | 
| 481         let block = <ts.ModuleBlock>node; | 533         let block = <ts.ModuleBlock>node; | 
| 482         this.visitMergingOverloads(block.statements); | 534         this.visitMergingOverloads(block.statements); | 
| 483       } break; | 535       } break; | 
| 484       case ts.SyntaxKind.VariableDeclarationList: { | 536       case ts.SyntaxKind.VariableDeclarationList: { | 
| 485         // We have to handle variable declaration lists differently in the case | 537         // We have to handle variable declaration lists differently in the case | 
| 486         // of JS interop because Dart does not support external variables. | 538         // of JS interop because Dart does not support external variables. | 
| 487         let varDeclList = <ts.VariableDeclarationList>node; | 539         let varDeclList = <ts.VariableDeclarationList>node; | 
| 488         this.visitList(varDeclList.declarations, ';'); | 540         this.visitList(varDeclList.declarations, ';'); | 
| 489       } break; | 541       } break; | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 523         this.visitParameters(fn.parameters); | 575         this.visitParameters(fn.parameters); | 
| 524         this.emitNoSpace(';'); | 576         this.emitNoSpace(';'); | 
| 525       } break; | 577       } break; | 
| 526       case ts.SyntaxKind.IndexSignature: | 578       case ts.SyntaxKind.IndexSignature: | 
| 527         this.emit('/* Index signature is not yet supported by JavaScript interop
     . */\n'); | 579         this.emit('/* Index signature is not yet supported by JavaScript interop
     . */\n'); | 
| 528         break; | 580         break; | 
| 529       case ts.SyntaxKind.ExportAssignment: | 581       case ts.SyntaxKind.ExportAssignment: | 
| 530         // let exportAssignment = <ts.ExportAssignment>node; | 582         // let exportAssignment = <ts.ExportAssignment>node; | 
| 531         this.emit('/* WARNING: export assignment not yet supported. */\n'); | 583         this.emit('/* WARNING: export assignment not yet supported. */\n'); | 
| 532         break; | 584         break; | 
| 533       case ts.SyntaxKind.TypeAliasDeclaration: | 585       case ts.SyntaxKind.TypeAliasDeclaration: { | 
| 534         // Dart does not provide special syntax for definning type alais | 586         // Object literal type alias declarations are equivalent to interface de
     clarations. | 
| 535         // declarations so we do not emit anything here and resolve alaises | 587         let alias = <ts.TypeAliasDeclaration>node; | 
| 536         // to their original types at each usage site. | 588         let type = alias.type; | 
| 537         break; | 589         if (type.kind === ts.SyntaxKind.TypeLiteral) { | 
|  | 590           let literal = <ts.TypeLiteralNode>type; | 
|  | 591           this.emit('@anonymous\n@JS()\n'); | 
|  | 592           this.visitClassLikeHelper( | 
|  | 593               'abstract class', literal, alias.name, alias.typeParameters, null)
     ; | 
|  | 594         } else if (type.kind === ts.SyntaxKind.FunctionType) { | 
|  | 595           // Function type alias definitions are equivalent to dart typedefs. | 
|  | 596           this.visitFunctionTypedefInterface( | 
|  | 597               base.ident(alias.name), type as ts.FunctionTypeNode, alias.typePar
     ameters); | 
|  | 598         } else { | 
|  | 599           this.enterCodeComment(); | 
|  | 600           this.emit(alias.getText()); | 
|  | 601           this.exitCodeComment(); | 
|  | 602           this.emit('\n'); | 
|  | 603         } | 
|  | 604         // We ignore other type alias declarations as Dart doesn't have a corres
     ponding feature yet. | 
|  | 605       } break; | 
| 538       case ts.SyntaxKind.ClassDeclaration: | 606       case ts.SyntaxKind.ClassDeclaration: | 
| 539       case ts.SyntaxKind.InterfaceDeclaration: { | 607       case ts.SyntaxKind.InterfaceDeclaration: { | 
| 540         this.extendsClass = false; | 608         this.extendsClass = false; | 
| 541         let classDecl = <ts.ClassDeclaration|ts.InterfaceDeclaration>node; | 609         let classDecl = <ts.ClassDeclaration|ts.InterfaceDeclaration>node; | 
| 542         let isInterface = node.kind === ts.SyntaxKind.InterfaceDeclaration; | 610         let isInterface = node.kind === ts.SyntaxKind.InterfaceDeclaration; | 
| 543         if (isInterface && | 611         if (isInterface && | 
| 544             base.isFunctionTypedefLikeInterface(classDecl as ts.InterfaceDeclara
     tion)) { | 612             base.isFunctionTypedefLikeInterface(classDecl as ts.InterfaceDeclara
     tion)) { | 
| 545           let member = <ts.CallSignatureDeclaration>classDecl.members[0]; | 613           let member = <ts.CallSignatureDeclaration>classDecl.members[0]; | 
| 546           this.visitFunctionTypedefInterface(classDecl.name.text, member, classD
     ecl.typeParameters); | 614           this.visitFunctionTypedefInterface(classDecl.name.text, member, classD
     ecl.typeParameters); | 
| 547           break; | 615           break; | 
| 548         } | 616         } | 
| 549 | 617 | 
| 550         let customName = this.fc.lookupCustomDartTypeName(classDecl.name, this.i
     nsideCodeComment); | 618         let customName = this.fc.lookupCustomDartTypeName(classDecl.name); | 
| 551         if (customName && !customName.keep) { | 619         if (customName && !customName.keep) { | 
| 552           this.emit('\n/* Skipping class ' + base.ident(classDecl.name) + '*/\n'
     ); | 620           this.emit('\n/* Skipping class ' + base.ident(classDecl.name) + '*/\n'
     ); | 
| 553           break; | 621           break; | 
| 554         } | 622         } | 
| 555         this.maybeEmitJsAnnotation(node); | 623         this.maybeEmitJsAnnotation(node); | 
| 556 | 624 | 
| 557         if (isInterface || | 625         if (isInterface || | 
| 558             (classDecl.modifiers && (classDecl.modifiers.flags & ts.NodeFlags.Ab
     stract))) { | 626             (classDecl.modifiers && (classDecl.modifiers.flags & ts.NodeFlags.Ab
     stract))) { | 
| 559           this.visitClassLike('abstract class', classDecl); | 627           this.visitClassLike('abstract class', classDecl); | 
| 560         } else { | 628         } else { | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 579         let exprWithTypeArgs = <ts.ExpressionWithTypeArguments>node; | 647         let exprWithTypeArgs = <ts.ExpressionWithTypeArguments>node; | 
| 580         this.visit(exprWithTypeArgs.expression); | 648         this.visit(exprWithTypeArgs.expression); | 
| 581         this.maybeVisitTypeArguments(exprWithTypeArgs); | 649         this.maybeVisitTypeArguments(exprWithTypeArgs); | 
| 582       } break; | 650       } break; | 
| 583       case ts.SyntaxKind.Constructor: | 651       case ts.SyntaxKind.Constructor: | 
| 584       case ts.SyntaxKind.ConstructSignature: { | 652       case ts.SyntaxKind.ConstructSignature: { | 
| 585         let ctorDecl = <ts.ConstructorDeclaration>node; | 653         let ctorDecl = <ts.ConstructorDeclaration>node; | 
| 586         // Find containing class name. | 654         // Find containing class name. | 
| 587         let classDecl = base.getEnclosingClass(ctorDecl); | 655         let classDecl = base.getEnclosingClass(ctorDecl); | 
| 588         if (!classDecl) this.reportError(ctorDecl, 'cannot find outer class node
     '); | 656         if (!classDecl) this.reportError(ctorDecl, 'cannot find outer class node
     '); | 
|  | 657         let isAnonymous = this.isAnonymousInterface(classDecl); | 
|  | 658         if (isAnonymous) { | 
|  | 659           this.emit('// Constructors on anonymous interfaces are not yet support
     ed.\n'); | 
|  | 660           this.enterCodeComment(); | 
|  | 661         } | 
| 589         this.visitDeclarationMetadata(ctorDecl); | 662         this.visitDeclarationMetadata(ctorDecl); | 
| 590         this.fc.visitTypeName(classDecl.name); | 663         this.fc.visitTypeName(classDecl.name); | 
| 591         this.visitParameters(ctorDecl.parameters); | 664         this.visitParameters(ctorDecl.parameters); | 
| 592         this.emitNoSpace(';'); | 665         this.emitNoSpace(';'); | 
|  | 666         if (isAnonymous) { | 
|  | 667           this.exitCodeComment(); | 
|  | 668           this.emit('\n'); | 
|  | 669         } | 
| 593       } break; | 670       } break; | 
| 594       case ts.SyntaxKind.PropertyDeclaration: | 671       case ts.SyntaxKind.PropertyDeclaration: | 
| 595         this.visitProperty(<ts.PropertyDeclaration>node); | 672         this.visitProperty(<ts.PropertyDeclaration>node); | 
| 596         break; | 673         break; | 
| 597       case ts.SyntaxKind.SemicolonClassElement: | 674       case ts.SyntaxKind.SemicolonClassElement: | 
| 598         // No-op, don't emit useless declarations. | 675         // No-op, don't emit useless declarations. | 
| 599         break; | 676         break; | 
| 600       case ts.SyntaxKind.MethodDeclaration: | 677       case ts.SyntaxKind.MethodDeclaration: | 
| 601         this.visitDeclarationMetadata(<ts.MethodDeclaration>node); | 678         this.visitDeclarationMetadata(<ts.MethodDeclaration>node); | 
| 602         this.visitFunctionLike(<ts.MethodDeclaration>node); | 679         this.visitFunctionLike(<ts.MethodDeclaration>node); | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 677         } | 754         } | 
| 678         this.fc.visitTypeName(<ts.Identifier>name); | 755         this.fc.visitTypeName(<ts.Identifier>name); | 
| 679       } | 756       } | 
| 680 | 757 | 
| 681       if (fn.typeParameters) { | 758       if (fn.typeParameters) { | 
| 682         let insideComment = this.insideCodeComment; | 759         let insideComment = this.insideCodeComment; | 
| 683         if (!insideComment) { | 760         if (!insideComment) { | 
| 684           this.enterCodeComment(); | 761           this.enterCodeComment(); | 
| 685         } | 762         } | 
| 686         this.emitNoSpace('<'); | 763         this.emitNoSpace('<'); | 
| 687         // Emit the names literally instead of visiting, otherwise they will be 
     replaced with the | 764         this.enterTypeArguments(); | 
| 688         // comment hack themselves. | 765         this.visitList(fn.typeParameters); | 
| 689         // TODO(jacobr): we can use the regular type parameter visiting pattern | 766         this.exitTypeArguments(); | 
| 690         // now that we properly track whether we are inside a comment. |  | 
| 691         this.emitNoSpace(fn.typeParameters.map(p => base.ident(p.name)).join(', 
     ')); |  | 
| 692         this.emitNoSpace('>'); | 767         this.emitNoSpace('>'); | 
| 693         if (!insideComment) { | 768         if (!insideComment) { | 
| 694           this.exitCodeComment(); | 769           this.exitCodeComment(); | 
| 695         } | 770         } | 
| 696       } | 771       } | 
| 697       // Dart does not even allow the parens of an empty param list on getter | 772       // Dart does not even allow the parens of an empty param list on getter | 
| 698       if (accessor !== 'get') { | 773       if (accessor !== 'get') { | 
| 699         this.visitParameters(fn.parameters); | 774         this.visitParameters(fn.parameters); | 
| 700       } else { | 775       } else { | 
| 701         if (fn.parameters && fn.parameters.length > 0) { | 776         if (fn.parameters && fn.parameters.length > 0) { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 731     this.emit('set'); | 806     this.emit('set'); | 
| 732     this.visitName(decl.name); | 807     this.visitName(decl.name); | 
| 733     this.emitNoSpace('('); | 808     this.emitNoSpace('('); | 
| 734     this.visit(decl.type); | 809     this.visit(decl.type); | 
| 735     this.emit('v'); | 810     this.emit('v'); | 
| 736     this.emitNoSpace(')'); | 811     this.emitNoSpace(')'); | 
| 737     this.emitNoSpace(';'); | 812     this.emitNoSpace(';'); | 
| 738   } | 813   } | 
| 739 | 814 | 
| 740   private visitClassLike(keyword: string, decl: base.ClassLike) { | 815   private visitClassLike(keyword: string, decl: base.ClassLike) { | 
|  | 816     return this.visitClassLikeHelper( | 
|  | 817         keyword, decl, decl.name, decl.typeParameters, decl.heritageClauses); | 
|  | 818   } | 
|  | 819 | 
|  | 820   private visitClassLikeHelper( | 
|  | 821       keyword: string, decl: base.ClassLike|ts.TypeLiteralNode, name: ts.Identif
     ier, | 
|  | 822       typeParameters: ts.NodeArray<ts.TypeParameterDeclaration>, | 
|  | 823       heritageClauses: ts.NodeArray<ts.HeritageClause>) { | 
| 741     this.emit(keyword); | 824     this.emit(keyword); | 
| 742     this.fc.visitTypeName(decl.name); | 825     this.fc.visitTypeName(name); | 
| 743     if (decl.typeParameters) { | 826     if (typeParameters) { | 
| 744       this.emit('<'); | 827       this.emit('<'); | 
| 745       this.visitList(decl.typeParameters); | 828       this.enterTypeArguments(); | 
|  | 829       this.visitList(typeParameters); | 
|  | 830       this.exitTypeArguments(); | 
| 746       this.emit('>'); | 831       this.emit('>'); | 
| 747     } | 832     } | 
| 748 | 833 | 
| 749     this.visitEachIfPresent(decl.heritageClauses); | 834     this.visitEachIfPresent(heritageClauses); | 
| 750     this.emit('{'); | 835     this.emit('{'); | 
| 751 | 836 | 
| 752     this.maybeEmitFakeConstructors(decl); | 837     this.maybeEmitFakeConstructors(decl); | 
| 753 | 838 | 
| 754     // Synthesize explicit properties for ctor with 'property parameters' | 839     // Synthesize explicit properties for ctor with 'property parameters' | 
| 755     let synthesizePropertyParam = (param: ts.ParameterDeclaration) => { | 840     let synthesizePropertyParam = (param: ts.ParameterDeclaration) => { | 
| 756       if (this.hasFlag(param.modifiers, ts.NodeFlags.Public) || | 841       if (this.hasFlag(param.modifiers, ts.NodeFlags.Public) || | 
| 757           this.hasFlag(param.modifiers, ts.NodeFlags.Private) || | 842           this.hasFlag(param.modifiers, ts.NodeFlags.Private) || | 
| 758           this.hasFlag(param.modifiers, ts.NodeFlags.Protected)) { | 843           this.hasFlag(param.modifiers, ts.NodeFlags.Protected)) { | 
| 759         // TODO: we should enforce the underscore prefix on privates | 844         // TODO: we should enforce the underscore prefix on privates | 
| 760         this.visitProperty(param, true); | 845         this.visitProperty(param, true); | 
| 761       } | 846       } | 
| 762     }; | 847     }; | 
| 763     (decl.members as ts.NodeArray<ts.Declaration>) | 848     (decl.members as ts.NodeArray<ts.Declaration>) | 
| 764         .filter(base.isConstructor) | 849         .filter(base.isConstructor) | 
| 765         .forEach( | 850         .forEach( | 
| 766             (ctor) => | 851             (ctor) => | 
| 767                 (<ts.ConstructorDeclaration>ctor).parameters.forEach(synthesizeP
     ropertyParam)); | 852                 (<ts.ConstructorDeclaration>ctor).parameters.forEach(synthesizeP
     ropertyParam)); | 
| 768 | 853 | 
| 769     this.visitClassBody(decl); | 854     this.visitClassBody(decl, name); | 
| 770     this.emit('}'); | 855     this.emit('}'); | 
| 771   } | 856   } | 
| 772 | 857 | 
| 773   private visitDeclarationMetadata(decl: ts.Declaration) { | 858   private visitDeclarationMetadata(decl: ts.Declaration) { | 
| 774     this.visitEachIfPresent(decl.modifiers); | 859     this.visitEachIfPresent(decl.modifiers); | 
| 775 | 860 | 
| 776     switch (decl.kind) { | 861     switch (decl.kind) { | 
| 777       case ts.SyntaxKind.Constructor: | 862       case ts.SyntaxKind.Constructor: | 
| 778       case ts.SyntaxKind.ConstructSignature: | 863       case ts.SyntaxKind.ConstructSignature: | 
| 779         this.emit('external factory'); | 864         this.emit('external factory'); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 794       default: | 879       default: | 
| 795         throw 'Unexpected declaration kind:' + decl.kind; | 880         throw 'Unexpected declaration kind:' + decl.kind; | 
| 796     } | 881     } | 
| 797   } | 882   } | 
| 798 | 883 | 
| 799   /** | 884   /** | 
| 800    * Handles a function typedef-like interface, i.e. an interface that only decl
     ares a single | 885    * Handles a function typedef-like interface, i.e. an interface that only decl
     ares a single | 
| 801    * call signature, by translating to a Dart `typedef`. | 886    * call signature, by translating to a Dart `typedef`. | 
| 802    */ | 887    */ | 
| 803   private visitFunctionTypedefInterface( | 888   private visitFunctionTypedefInterface( | 
| 804       name: string, signature: ts.CallSignatureDeclaration, | 889       name: string, signature: ts.SignatureDeclaration, | 
| 805       typeParameters: ts.NodeArray<ts.TypeParameterDeclaration>) { | 890       typeParameters: ts.NodeArray<ts.TypeParameterDeclaration>) { | 
| 806     this.emit('typedef'); | 891     this.emit('typedef'); | 
| 807     if (signature.type) { | 892     if (signature.type) { | 
| 808       this.visit(signature.type); | 893       this.visit(signature.type); | 
| 809     } | 894     } | 
| 810     this.emit(name); | 895     this.emit(name); | 
| 811     if (typeParameters) { | 896     if (typeParameters) { | 
| 812       this.emitNoSpace('<'); | 897       this.emitNoSpace('<'); | 
|  | 898       this.enterTypeArguments(); | 
| 813       this.visitList(typeParameters); | 899       this.visitList(typeParameters); | 
|  | 900       this.exitTypeArguments(); | 
| 814       this.emitNoSpace('>'); | 901       this.emitNoSpace('>'); | 
| 815     } | 902     } | 
| 816     this.visitParameters(signature.parameters); | 903     this.visitParameters(signature.parameters); | 
| 817     this.emitNoSpace(';'); | 904     this.emitNoSpace(';'); | 
| 818   } | 905   } | 
| 819 } | 906 } | 
| OLD | NEW | 
|---|