1//// [parserRealSource8.ts] 2// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 3// See LICENSE.txt in the project root for complete license information. 4 5///<reference path='typescript.ts' /> 6 7module TypeScript { 8 9 export class AssignScopeContext { 10 constructor (public scopeChain: ScopeChain, 11 public typeFlow: TypeFlow, 12 public modDeclChain: ModuleDeclaration[]) { 13 } 14 } 15 16 export function pushAssignScope(scope: SymbolScope, 17 context: AssignScopeContext, 18 type: Type, 19 classType: Type, 20 fnc: FuncDecl) { 21 22 var chain = new ScopeChain(null, context.scopeChain, scope); 23 chain.thisType = type; 24 chain.classType = classType; 25 chain.fnc = fnc; 26 context.scopeChain = chain; 27 } 28 29 export function popAssignScope(context: AssignScopeContext) { 30 context.scopeChain = context.scopeChain.previous; 31 } 32 33 export function instanceCompare(a: Symbol, b: Symbol) { 34 if (((a == null) || (!a.isInstanceProperty()))) { 35 return b; 36 } 37 else { 38 return a; 39 } 40 } 41 42 export function instanceFilterStop(s: Symbol) { 43 return s.isInstanceProperty(); 44 } 45 46 export class ScopeSearchFilter { 47 48 constructor (public select: (a: Symbol, b: Symbol) =>Symbol, 49 public stop: (s: Symbol) =>boolean) { } 50 51 public result: Symbol = null; 52 53 public reset() { 54 this.result = null; 55 } 56 57 public update(b: Symbol): boolean { 58 this.result = this.select(this.result, b); 59 if (this.result) { 60 return this.stop(this.result); 61 } 62 else { 63 return false; 64 } 65 } 66 } 67 68 export var instanceFilter = new ScopeSearchFilter(instanceCompare, instanceFilterStop); 69 70 export function preAssignModuleScopes(ast: AST, context: AssignScopeContext) { 71 var moduleDecl = <ModuleDeclaration>ast; 72 var memberScope: SymbolTableScope = null; 73 var aggScope: SymbolAggregateScope = null; 74 75 if (moduleDecl.name && moduleDecl.mod) { 76 moduleDecl.name.sym = moduleDecl.mod.symbol; 77 } 78 79 var mod = moduleDecl.mod; 80 81 // We're likely here because of error recovery 82 if (!mod) { 83 return; 84 } 85 86 memberScope = new SymbolTableScope(mod.members, mod.ambientMembers, mod.enclosedTypes, mod.ambientEnclosedTypes, mod.symbol); 87 mod.memberScope = memberScope; 88 context.modDeclChain.push(moduleDecl); 89 context.typeFlow.checker.currentModDecl = moduleDecl; 90 aggScope = new SymbolAggregateScope(mod.symbol); 91 aggScope.addParentScope(memberScope); 92 aggScope.addParentScope(context.scopeChain.scope); 93 pushAssignScope(aggScope, context, null, null, null); 94 mod.containedScope = aggScope; 95 if (mod.symbol) { 96 context.typeFlow.addLocalsFromScope(mod.containedScope, mod.symbol, moduleDecl.vars, mod.members.privateMembers, true); 97 } 98 } 99 100 export function preAssignClassScopes(ast: AST, context: AssignScopeContext) { 101 var classDecl = <InterfaceDeclaration>ast; 102 var memberScope: SymbolTableScope = null; 103 var aggScope: SymbolAggregateScope = null; 104 105 if (classDecl.name && classDecl.type) { 106 classDecl.name.sym = classDecl.type.symbol; 107 } 108 109 var classType = ast.type; 110 111 if (classType) { 112 var classSym = classType.symbol; 113 memberScope = <SymbolTableScope>context.typeFlow.checker.scopeOf(classType); 114 115 aggScope = new SymbolAggregateScope(classType.symbol); 116 aggScope.addParentScope(memberScope); 117 aggScope.addParentScope(context.scopeChain.scope); 118 119 classType.containedScope = aggScope; 120 classType.memberScope = memberScope; 121 122 var instanceType = classType.instanceType; 123 memberScope = <SymbolTableScope>context.typeFlow.checker.scopeOf(instanceType); 124 instanceType.memberScope = memberScope; 125 126 aggScope = new SymbolAggregateScope(instanceType.symbol); 127 aggScope.addParentScope(context.scopeChain.scope); 128 129 pushAssignScope(aggScope, context, instanceType, classType, null); 130 instanceType.containedScope = aggScope; 131 } 132 else { 133 ast.type = context.typeFlow.anyType; 134 } 135 } 136 137 export function preAssignInterfaceScopes(ast: AST, context: AssignScopeContext) { 138 var interfaceDecl = <InterfaceDeclaration>ast; 139 var memberScope: SymbolTableScope = null; 140 var aggScope: SymbolAggregateScope = null; 141 142 if (interfaceDecl.name && interfaceDecl.type) { 143 interfaceDecl.name.sym = interfaceDecl.type.symbol; 144 } 145 146 var interfaceType = ast.type; 147 memberScope = <SymbolTableScope>context.typeFlow.checker.scopeOf(interfaceType); 148 interfaceType.memberScope = memberScope; 149 aggScope = new SymbolAggregateScope(interfaceType.symbol); 150 aggScope.addParentScope(memberScope); 151 aggScope.addParentScope(context.scopeChain.scope); 152 pushAssignScope(aggScope, context, null, null, null); 153 interfaceType.containedScope = aggScope; 154 } 155 156 export function preAssignWithScopes(ast: AST, context: AssignScopeContext) { 157 var withStmt = <WithStatement>ast; 158 var withType = withStmt.type; 159 160 var members = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); 161 var ambientMembers = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); 162 163 var withType = new Type(); 164 var withSymbol = new WithSymbol(withStmt.minChar, context.typeFlow.checker.locationInfo.unitIndex, withType); 165 withType.members = members; 166 withType.ambientMembers = ambientMembers; 167 withType.symbol = withSymbol; 168 withType.setHasImplementation(); 169 withStmt.type = withType; 170 171 var withScope = new TypeScript.SymbolScopeBuilder(withType.members, withType.ambientMembers, null, null, context.scopeChain.scope, withType.symbol); 172 173 pushAssignScope(withScope, context, null, null, null); 174 withType.containedScope = withScope; 175 } 176 177 export function preAssignFuncDeclScopes(ast: AST, context: AssignScopeContext) { 178 var funcDecl = <FuncDecl>ast; 179 180 var container: Symbol = null; 181 var localContainer: Symbol = null; 182 if (funcDecl.type) { 183 localContainer = ast.type.symbol; 184 } 185 186 var isStatic = hasFlag(funcDecl.fncFlags, FncFlags.Static); 187 var isInnerStatic = isStatic && context.scopeChain.fnc != null; 188 // for inner static functions, use the parent's member scope, so local vars cannot be captured 189 var parentScope = isInnerStatic ? context.scopeChain.fnc.type.memberScope : context.scopeChain.scope; 190 191 // if this is not a method, but enclosed by class, use constructor as 192 // the enclosing scope 193 // REVIEW: Some twisted logic here - this needs to be cleaned up once old classes are removed 194 // - if it's a new class, always use the contained scope, since we initialize the constructor scope below 195 if (context.scopeChain.thisType && 196 (!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod))) { 197 var instType = context.scopeChain.thisType; 198 199 if (!(instType.typeFlags & TypeFlags.IsClass) && !hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) { 200 if (!funcDecl.isMethod() || isStatic) { 201 parentScope = instType.constructorScope; 202 } 203 else { 204 // use constructor scope if a method as well 205 parentScope = instType.containedScope; 206 } 207 } 208 else { 209 if (context.scopeChain.previous.scope.container && 210 context.scopeChain.previous.scope.container.declAST && 211 context.scopeChain.previous.scope.container.declAST.nodeType == NodeType.FuncDecl && 212 (<FuncDecl>context.scopeChain.previous.scope.container.declAST).isConstructor) { 213 214 // if the parent is the class constructor, use the constructor scope 215 parentScope = instType.constructorScope; 216 } 217 else if (isStatic && context.scopeChain.classType) { 218 parentScope = context.scopeChain.classType.containedScope; 219 } 220 else { 221 // else, use the contained scope 222 parentScope = instType.containedScope; 223 } 224 } 225 container = instType.symbol; 226 } 227 else if (funcDecl.isConstructor && context.scopeChain.thisType) { 228 // sets the container to the class type's symbol (which is shared by the instance type) 229 container = context.scopeChain.thisType.symbol; 230 } 231 232 if (funcDecl.type == null || hasFlag(funcDecl.type.symbol.flags, SymbolFlags.TypeSetDuringScopeAssignment)) { 233 if (context.scopeChain.fnc && context.scopeChain.fnc.type) { 234 container = context.scopeChain.fnc.type.symbol; 235 } 236 237 var funcScope = null; 238 var outerFnc: FuncDecl = context.scopeChain.fnc; 239 var nameText = funcDecl.name ? funcDecl.name.actualText : null; 240 var fgSym: TypeSymbol = null; 241 242 if (isStatic) { 243 // In the case of function-nested statics, no member list will have bee initialized for the function, so we need 244 // to copy it over. We don't set this by default because having a non-null member list will throw off assignment 245 // compatibility tests 246 if (outerFnc.type.members == null && container.getType().memberScope) { 247 outerFnc.type.members = (<SymbolScopeBuilder>(<TypeSymbol>container).type.memberScope).valueMembers; 248 } 249 funcScope = context.scopeChain.fnc.type.memberScope; 250 outerFnc.innerStaticFuncs[outerFnc.innerStaticFuncs.length] = funcDecl; 251 } 252 else { 253 254 if (!funcDecl.isConstructor && 255 container && 256 container.declAST && 257 container.declAST.nodeType == NodeType.FuncDecl && 258 (<FuncDecl>container.declAST).isConstructor && 259 !funcDecl.isMethod()) { 260 funcScope = context.scopeChain.thisType.constructorScope;//locals; 261 } 262 else { 263 funcScope = context.scopeChain.scope; 264 } 265 } 266 267 // REVIEW: We don't search for another sym for accessors to prevent us from 268 // accidentally coalescing function signatures with the same name (E.g., a function 269 // 'f' the outer scope and a setter 'f' in an object literal within that scope) 270 if (nameText && nameText != "__missing" && !funcDecl.isAccessor()) { 271 if (isStatic) { 272 fgSym = funcScope.findLocal(nameText, false, false); 273 } 274 else { 275 // REVIEW: This logic should be symmetric with preCollectClassTypes 276 fgSym = funcScope.findLocal(nameText, false, false); 277 } 278 } 279 280 context.typeFlow.checker.createFunctionSignature(funcDecl, container, 281 funcScope, fgSym, fgSym == null); 282 283 // it's a getter or setter for a class property 284 if (!funcDecl.accessorSymbol && 285 (funcDecl.fncFlags & FncFlags.ClassMethod) && 286 container && 287 ((!fgSym || fgSym.declAST.nodeType != NodeType.FuncDecl) && funcDecl.isAccessor()) || 288 (fgSym && fgSym.isAccessor())) 289 { 290 funcDecl.accessorSymbol = context.typeFlow.checker.createAccessorSymbol(funcDecl, fgSym, container.getType(), (funcDecl.isMethod() && isStatic), true, funcScope, container); 291 } 292 293 funcDecl.type.symbol.flags |= SymbolFlags.TypeSetDuringScopeAssignment; 294 } 295 296 // Set the symbol for functions and their overloads 297 if (funcDecl.name && funcDecl.type) { 298 funcDecl.name.sym = funcDecl.type.symbol; 299 } 300 301 // Keep track of the original scope type, because target typing might override 302 // the "type" member. We need the original "Scope type" for completion list, etc. 303 funcDecl.scopeType = funcDecl.type; 304 305 // Overloads have no scope, so bail here 306 if (funcDecl.isOverload) { 307 return; 308 } 309 310 var funcTable = new StringHashTable(); 311 var funcMembers = new ScopedMembers(new DualStringHashTable(funcTable, new StringHashTable())); 312 var ambientFuncTable = new StringHashTable(); 313 var ambientFuncMembers = new ScopedMembers(new DualStringHashTable(ambientFuncTable, new StringHashTable())); 314 var funcStaticTable = new StringHashTable(); 315 var funcStaticMembers = new ScopedMembers(new DualStringHashTable(funcStaticTable, new StringHashTable())); 316 var ambientFuncStaticTable = new StringHashTable(); 317 var ambientFuncStaticMembers = new ScopedMembers(new DualStringHashTable(ambientFuncStaticTable, new StringHashTable())); 318 319 // REVIEW: Is it a problem that this is being set twice for properties and constructors? 320 funcDecl.unitIndex = context.typeFlow.checker.locationInfo.unitIndex; 321 322 var locals = new SymbolScopeBuilder(funcMembers, ambientFuncMembers, null, null, parentScope, localContainer); 323 var statics = new SymbolScopeBuilder(funcStaticMembers, ambientFuncStaticMembers, null, null, parentScope, null); 324 325 if (funcDecl.isConstructor && context.scopeChain.thisType) { 326 context.scopeChain.thisType.constructorScope = locals; 327 } 328 329 // basically, there are two problems 330 // - Above, for new classes, we were overwriting the constructor scope with the containing scope. This caused constructor params to be 331 // in scope everywhere 332 // - Below, we're setting the contained scope table to the same table we were overwriting the constructor scope with, which we need to 333 // fish lambda params, etc, out (see funcTable below) 334 // 335 // A good first approach to solving this would be to change addLocalsFromScope to take a scope instead of a table, and add to the 336 // constructor scope as appropriate 337 338 funcDecl.symbols = funcTable; 339 340 if (!funcDecl.isSpecialFn()) { 341 var group = funcDecl.type; 342 var signature = funcDecl.signature; 343 344 if (!funcDecl.isConstructor) { 345 group.containedScope = locals; 346 locals.container = group.symbol; 347 348 group.memberScope = statics; 349 statics.container = group.symbol; 350 } 351 funcDecl.enclosingFnc = context.scopeChain.fnc; 352 group.enclosingType = isStatic ? context.scopeChain.classType : context.scopeChain.thisType; 353 // for mapping when type checking 354 var fgSym = <TypeSymbol>ast.type.symbol; 355 if (((funcDecl.fncFlags & FncFlags.Signature) == FncFlags.None) && funcDecl.vars) { 356 context.typeFlow.addLocalsFromScope(locals, fgSym, funcDecl.vars, 357 funcTable, false); 358 context.typeFlow.addLocalsFromScope(statics, fgSym, funcDecl.statics, 359 funcStaticTable, false); 360 } 361 if (signature.parameters) { 362 var len = signature.parameters.length; 363 for (var i = 0; i < len; i++) { 364 var paramSym: ParameterSymbol = signature.parameters[i]; 365 context.typeFlow.checker.resolveTypeLink(locals, 366 paramSym.parameter.typeLink, true); 367 } 368 } 369 context.typeFlow.checker.resolveTypeLink(locals, signature.returnType, 370 funcDecl.isSignature()); 371 } 372 373 if (!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) { 374 var thisType = (funcDecl.isConstructor && hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) ? context.scopeChain.thisType : null; 375 pushAssignScope(locals, context, thisType, null, funcDecl); 376 } 377 } 378 379 export function preAssignCatchScopes(ast: AST, context: AssignScopeContext) { 380 var catchBlock = <Catch>ast; 381 if (catchBlock.param) { 382 var catchTable = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); // REVIEW: Should we be allocating a public table instead of a private one? 383 var catchLocals = new SymbolScopeBuilder(catchTable, null, null, null, context.scopeChain.scope, 384 context.scopeChain.scope.container); 385 catchBlock.containedScope = catchLocals; 386 pushAssignScope(catchLocals, context, context.scopeChain.thisType, context.scopeChain.classType, context.scopeChain.fnc); 387 } 388 } 389 390 export function preAssignScopes(ast: AST, parent: AST, walker: IAstWalker) { 391 var context:AssignScopeContext = walker.state; 392 var go = true; 393 394 if (ast) { 395 if (ast.nodeType == NodeType.List) { 396 var list = <ASTList>ast; 397 list.enclosingScope = context.scopeChain.scope; 398 } 399 else if (ast.nodeType == NodeType.ModuleDeclaration) { 400 preAssignModuleScopes(ast, context); 401 } 402 else if (ast.nodeType == NodeType.ClassDeclaration) { 403 preAssignClassScopes(ast, context); 404 } 405 else if (ast.nodeType == NodeType.InterfaceDeclaration) { 406 preAssignInterfaceScopes(ast, context); 407 } 408 else if (ast.nodeType == NodeType.With) { 409 preAssignWithScopes(ast, context); 410 } 411 else if (ast.nodeType == NodeType.FuncDecl) { 412 preAssignFuncDeclScopes(ast, context); 413 } 414 else if (ast.nodeType == NodeType.Catch) { 415 preAssignCatchScopes(ast, context); 416 } 417 else if (ast.nodeType == NodeType.TypeRef) { 418 go = false; 419 } 420 } 421 walker.options.goChildren = go; 422 return ast; 423 } 424 425 export function postAssignScopes(ast: AST, parent: AST, walker: IAstWalker) { 426 var context:AssignScopeContext = walker.state; 427 var go = true; 428 if (ast) { 429 if (ast.nodeType == NodeType.ModuleDeclaration) { 430 var prevModDecl = <ModuleDeclaration>ast; 431 432 popAssignScope(context); 433 434 context.modDeclChain.pop(); 435 if (context.modDeclChain.length >= 1) { 436 context.typeFlow.checker.currentModDecl = context.modDeclChain[context.modDeclChain.length - 1]; 437 } 438 } 439 else if (ast.nodeType == NodeType.ClassDeclaration) { 440 popAssignScope(context); 441 } 442 else if (ast.nodeType == NodeType.InterfaceDeclaration) { 443 popAssignScope(context); 444 } 445 else if (ast.nodeType == NodeType.With) { 446 popAssignScope(context); 447 } 448 else if (ast.nodeType == NodeType.FuncDecl) { 449 var funcDecl = <FuncDecl>ast; 450 if ((!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) && !funcDecl.isOverload) { 451 popAssignScope(context); 452 } 453 } 454 else if (ast.nodeType == NodeType.Catch) { 455 var catchBlock = <Catch>ast; 456 if (catchBlock.param) { 457 popAssignScope(context); 458 } 459 } 460 else { 461 go = false; 462 } 463 } 464 walker.options.goChildren = go; 465 return ast; 466 } 467} 468 469//// [parserRealSource8.js] 470// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 471// See LICENSE.txt in the project root for complete license information. 472///<reference path='typescript.ts' /> 473var TypeScript; 474(function (TypeScript) { 475 var AssignScopeContext = /** @class */ (function () { 476 function AssignScopeContext(scopeChain, typeFlow, modDeclChain) { 477 this.scopeChain = scopeChain; 478 this.typeFlow = typeFlow; 479 this.modDeclChain = modDeclChain; 480 } 481 return AssignScopeContext; 482 }()); 483 TypeScript.AssignScopeContext = AssignScopeContext; 484 function pushAssignScope(scope, context, type, classType, fnc) { 485 var chain = new ScopeChain(null, context.scopeChain, scope); 486 chain.thisType = type; 487 chain.classType = classType; 488 chain.fnc = fnc; 489 context.scopeChain = chain; 490 } 491 TypeScript.pushAssignScope = pushAssignScope; 492 function popAssignScope(context) { 493 context.scopeChain = context.scopeChain.previous; 494 } 495 TypeScript.popAssignScope = popAssignScope; 496 function instanceCompare(a, b) { 497 if (((a == null) || (!a.isInstanceProperty()))) { 498 return b; 499 } 500 else { 501 return a; 502 } 503 } 504 TypeScript.instanceCompare = instanceCompare; 505 function instanceFilterStop(s) { 506 return s.isInstanceProperty(); 507 } 508 TypeScript.instanceFilterStop = instanceFilterStop; 509 var ScopeSearchFilter = /** @class */ (function () { 510 function ScopeSearchFilter(select, stop) { 511 this.select = select; 512 this.stop = stop; 513 this.result = null; 514 } 515 ScopeSearchFilter.prototype.reset = function () { 516 this.result = null; 517 }; 518 ScopeSearchFilter.prototype.update = function (b) { 519 this.result = this.select(this.result, b); 520 if (this.result) { 521 return this.stop(this.result); 522 } 523 else { 524 return false; 525 } 526 }; 527 return ScopeSearchFilter; 528 }()); 529 TypeScript.ScopeSearchFilter = ScopeSearchFilter; 530 TypeScript.instanceFilter = new ScopeSearchFilter(instanceCompare, instanceFilterStop); 531 function preAssignModuleScopes(ast, context) { 532 var moduleDecl = ast; 533 var memberScope = null; 534 var aggScope = null; 535 if (moduleDecl.name && moduleDecl.mod) { 536 moduleDecl.name.sym = moduleDecl.mod.symbol; 537 } 538 var mod = moduleDecl.mod; 539 // We're likely here because of error recovery 540 if (!mod) { 541 return; 542 } 543 memberScope = new SymbolTableScope(mod.members, mod.ambientMembers, mod.enclosedTypes, mod.ambientEnclosedTypes, mod.symbol); 544 mod.memberScope = memberScope; 545 context.modDeclChain.push(moduleDecl); 546 context.typeFlow.checker.currentModDecl = moduleDecl; 547 aggScope = new SymbolAggregateScope(mod.symbol); 548 aggScope.addParentScope(memberScope); 549 aggScope.addParentScope(context.scopeChain.scope); 550 pushAssignScope(aggScope, context, null, null, null); 551 mod.containedScope = aggScope; 552 if (mod.symbol) { 553 context.typeFlow.addLocalsFromScope(mod.containedScope, mod.symbol, moduleDecl.vars, mod.members.privateMembers, true); 554 } 555 } 556 TypeScript.preAssignModuleScopes = preAssignModuleScopes; 557 function preAssignClassScopes(ast, context) { 558 var classDecl = ast; 559 var memberScope = null; 560 var aggScope = null; 561 if (classDecl.name && classDecl.type) { 562 classDecl.name.sym = classDecl.type.symbol; 563 } 564 var classType = ast.type; 565 if (classType) { 566 var classSym = classType.symbol; 567 memberScope = context.typeFlow.checker.scopeOf(classType); 568 aggScope = new SymbolAggregateScope(classType.symbol); 569 aggScope.addParentScope(memberScope); 570 aggScope.addParentScope(context.scopeChain.scope); 571 classType.containedScope = aggScope; 572 classType.memberScope = memberScope; 573 var instanceType = classType.instanceType; 574 memberScope = context.typeFlow.checker.scopeOf(instanceType); 575 instanceType.memberScope = memberScope; 576 aggScope = new SymbolAggregateScope(instanceType.symbol); 577 aggScope.addParentScope(context.scopeChain.scope); 578 pushAssignScope(aggScope, context, instanceType, classType, null); 579 instanceType.containedScope = aggScope; 580 } 581 else { 582 ast.type = context.typeFlow.anyType; 583 } 584 } 585 TypeScript.preAssignClassScopes = preAssignClassScopes; 586 function preAssignInterfaceScopes(ast, context) { 587 var interfaceDecl = ast; 588 var memberScope = null; 589 var aggScope = null; 590 if (interfaceDecl.name && interfaceDecl.type) { 591 interfaceDecl.name.sym = interfaceDecl.type.symbol; 592 } 593 var interfaceType = ast.type; 594 memberScope = context.typeFlow.checker.scopeOf(interfaceType); 595 interfaceType.memberScope = memberScope; 596 aggScope = new SymbolAggregateScope(interfaceType.symbol); 597 aggScope.addParentScope(memberScope); 598 aggScope.addParentScope(context.scopeChain.scope); 599 pushAssignScope(aggScope, context, null, null, null); 600 interfaceType.containedScope = aggScope; 601 } 602 TypeScript.preAssignInterfaceScopes = preAssignInterfaceScopes; 603 function preAssignWithScopes(ast, context) { 604 var withStmt = ast; 605 var withType = withStmt.type; 606 var members = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); 607 var ambientMembers = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); 608 var withType = new Type(); 609 var withSymbol = new WithSymbol(withStmt.minChar, context.typeFlow.checker.locationInfo.unitIndex, withType); 610 withType.members = members; 611 withType.ambientMembers = ambientMembers; 612 withType.symbol = withSymbol; 613 withType.setHasImplementation(); 614 withStmt.type = withType; 615 var withScope = new TypeScript.SymbolScopeBuilder(withType.members, withType.ambientMembers, null, null, context.scopeChain.scope, withType.symbol); 616 pushAssignScope(withScope, context, null, null, null); 617 withType.containedScope = withScope; 618 } 619 TypeScript.preAssignWithScopes = preAssignWithScopes; 620 function preAssignFuncDeclScopes(ast, context) { 621 var funcDecl = ast; 622 var container = null; 623 var localContainer = null; 624 if (funcDecl.type) { 625 localContainer = ast.type.symbol; 626 } 627 var isStatic = hasFlag(funcDecl.fncFlags, FncFlags.Static); 628 var isInnerStatic = isStatic && context.scopeChain.fnc != null; 629 // for inner static functions, use the parent's member scope, so local vars cannot be captured 630 var parentScope = isInnerStatic ? context.scopeChain.fnc.type.memberScope : context.scopeChain.scope; 631 // if this is not a method, but enclosed by class, use constructor as 632 // the enclosing scope 633 // REVIEW: Some twisted logic here - this needs to be cleaned up once old classes are removed 634 // - if it's a new class, always use the contained scope, since we initialize the constructor scope below 635 if (context.scopeChain.thisType && 636 (!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod))) { 637 var instType = context.scopeChain.thisType; 638 if (!(instType.typeFlags & TypeFlags.IsClass) && !hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) { 639 if (!funcDecl.isMethod() || isStatic) { 640 parentScope = instType.constructorScope; 641 } 642 else { 643 // use constructor scope if a method as well 644 parentScope = instType.containedScope; 645 } 646 } 647 else { 648 if (context.scopeChain.previous.scope.container && 649 context.scopeChain.previous.scope.container.declAST && 650 context.scopeChain.previous.scope.container.declAST.nodeType == NodeType.FuncDecl && 651 context.scopeChain.previous.scope.container.declAST.isConstructor) { 652 // if the parent is the class constructor, use the constructor scope 653 parentScope = instType.constructorScope; 654 } 655 else if (isStatic && context.scopeChain.classType) { 656 parentScope = context.scopeChain.classType.containedScope; 657 } 658 else { 659 // else, use the contained scope 660 parentScope = instType.containedScope; 661 } 662 } 663 container = instType.symbol; 664 } 665 else if (funcDecl.isConstructor && context.scopeChain.thisType) { 666 // sets the container to the class type's symbol (which is shared by the instance type) 667 container = context.scopeChain.thisType.symbol; 668 } 669 if (funcDecl.type == null || hasFlag(funcDecl.type.symbol.flags, SymbolFlags.TypeSetDuringScopeAssignment)) { 670 if (context.scopeChain.fnc && context.scopeChain.fnc.type) { 671 container = context.scopeChain.fnc.type.symbol; 672 } 673 var funcScope = null; 674 var outerFnc = context.scopeChain.fnc; 675 var nameText = funcDecl.name ? funcDecl.name.actualText : null; 676 var fgSym = null; 677 if (isStatic) { 678 // In the case of function-nested statics, no member list will have bee initialized for the function, so we need 679 // to copy it over. We don't set this by default because having a non-null member list will throw off assignment 680 // compatibility tests 681 if (outerFnc.type.members == null && container.getType().memberScope) { 682 outerFnc.type.members = container.type.memberScope.valueMembers; 683 } 684 funcScope = context.scopeChain.fnc.type.memberScope; 685 outerFnc.innerStaticFuncs[outerFnc.innerStaticFuncs.length] = funcDecl; 686 } 687 else { 688 if (!funcDecl.isConstructor && 689 container && 690 container.declAST && 691 container.declAST.nodeType == NodeType.FuncDecl && 692 container.declAST.isConstructor && 693 !funcDecl.isMethod()) { 694 funcScope = context.scopeChain.thisType.constructorScope; //locals; 695 } 696 else { 697 funcScope = context.scopeChain.scope; 698 } 699 } 700 // REVIEW: We don't search for another sym for accessors to prevent us from 701 // accidentally coalescing function signatures with the same name (E.g., a function 702 // 'f' the outer scope and a setter 'f' in an object literal within that scope) 703 if (nameText && nameText != "__missing" && !funcDecl.isAccessor()) { 704 if (isStatic) { 705 fgSym = funcScope.findLocal(nameText, false, false); 706 } 707 else { 708 // REVIEW: This logic should be symmetric with preCollectClassTypes 709 fgSym = funcScope.findLocal(nameText, false, false); 710 } 711 } 712 context.typeFlow.checker.createFunctionSignature(funcDecl, container, funcScope, fgSym, fgSym == null); 713 // it's a getter or setter for a class property 714 if (!funcDecl.accessorSymbol && 715 (funcDecl.fncFlags & FncFlags.ClassMethod) && 716 container && 717 ((!fgSym || fgSym.declAST.nodeType != NodeType.FuncDecl) && funcDecl.isAccessor()) || 718 (fgSym && fgSym.isAccessor())) { 719 funcDecl.accessorSymbol = context.typeFlow.checker.createAccessorSymbol(funcDecl, fgSym, container.getType(), (funcDecl.isMethod() && isStatic), true, funcScope, container); 720 } 721 funcDecl.type.symbol.flags |= SymbolFlags.TypeSetDuringScopeAssignment; 722 } 723 // Set the symbol for functions and their overloads 724 if (funcDecl.name && funcDecl.type) { 725 funcDecl.name.sym = funcDecl.type.symbol; 726 } 727 // Keep track of the original scope type, because target typing might override 728 // the "type" member. We need the original "Scope type" for completion list, etc. 729 funcDecl.scopeType = funcDecl.type; 730 // Overloads have no scope, so bail here 731 if (funcDecl.isOverload) { 732 return; 733 } 734 var funcTable = new StringHashTable(); 735 var funcMembers = new ScopedMembers(new DualStringHashTable(funcTable, new StringHashTable())); 736 var ambientFuncTable = new StringHashTable(); 737 var ambientFuncMembers = new ScopedMembers(new DualStringHashTable(ambientFuncTable, new StringHashTable())); 738 var funcStaticTable = new StringHashTable(); 739 var funcStaticMembers = new ScopedMembers(new DualStringHashTable(funcStaticTable, new StringHashTable())); 740 var ambientFuncStaticTable = new StringHashTable(); 741 var ambientFuncStaticMembers = new ScopedMembers(new DualStringHashTable(ambientFuncStaticTable, new StringHashTable())); 742 // REVIEW: Is it a problem that this is being set twice for properties and constructors? 743 funcDecl.unitIndex = context.typeFlow.checker.locationInfo.unitIndex; 744 var locals = new SymbolScopeBuilder(funcMembers, ambientFuncMembers, null, null, parentScope, localContainer); 745 var statics = new SymbolScopeBuilder(funcStaticMembers, ambientFuncStaticMembers, null, null, parentScope, null); 746 if (funcDecl.isConstructor && context.scopeChain.thisType) { 747 context.scopeChain.thisType.constructorScope = locals; 748 } 749 // basically, there are two problems 750 // - Above, for new classes, we were overwriting the constructor scope with the containing scope. This caused constructor params to be 751 // in scope everywhere 752 // - Below, we're setting the contained scope table to the same table we were overwriting the constructor scope with, which we need to 753 // fish lambda params, etc, out (see funcTable below) 754 // 755 // A good first approach to solving this would be to change addLocalsFromScope to take a scope instead of a table, and add to the 756 // constructor scope as appropriate 757 funcDecl.symbols = funcTable; 758 if (!funcDecl.isSpecialFn()) { 759 var group = funcDecl.type; 760 var signature = funcDecl.signature; 761 if (!funcDecl.isConstructor) { 762 group.containedScope = locals; 763 locals.container = group.symbol; 764 group.memberScope = statics; 765 statics.container = group.symbol; 766 } 767 funcDecl.enclosingFnc = context.scopeChain.fnc; 768 group.enclosingType = isStatic ? context.scopeChain.classType : context.scopeChain.thisType; 769 // for mapping when type checking 770 var fgSym = ast.type.symbol; 771 if (((funcDecl.fncFlags & FncFlags.Signature) == FncFlags.None) && funcDecl.vars) { 772 context.typeFlow.addLocalsFromScope(locals, fgSym, funcDecl.vars, funcTable, false); 773 context.typeFlow.addLocalsFromScope(statics, fgSym, funcDecl.statics, funcStaticTable, false); 774 } 775 if (signature.parameters) { 776 var len = signature.parameters.length; 777 for (var i = 0; i < len; i++) { 778 var paramSym = signature.parameters[i]; 779 context.typeFlow.checker.resolveTypeLink(locals, paramSym.parameter.typeLink, true); 780 } 781 } 782 context.typeFlow.checker.resolveTypeLink(locals, signature.returnType, funcDecl.isSignature()); 783 } 784 if (!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) { 785 var thisType = (funcDecl.isConstructor && hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) ? context.scopeChain.thisType : null; 786 pushAssignScope(locals, context, thisType, null, funcDecl); 787 } 788 } 789 TypeScript.preAssignFuncDeclScopes = preAssignFuncDeclScopes; 790 function preAssignCatchScopes(ast, context) { 791 var catchBlock = ast; 792 if (catchBlock.param) { 793 var catchTable = new ScopedMembers(new DualStringHashTable(new StringHashTable(), new StringHashTable())); // REVIEW: Should we be allocating a public table instead of a private one? 794 var catchLocals = new SymbolScopeBuilder(catchTable, null, null, null, context.scopeChain.scope, context.scopeChain.scope.container); 795 catchBlock.containedScope = catchLocals; 796 pushAssignScope(catchLocals, context, context.scopeChain.thisType, context.scopeChain.classType, context.scopeChain.fnc); 797 } 798 } 799 TypeScript.preAssignCatchScopes = preAssignCatchScopes; 800 function preAssignScopes(ast, parent, walker) { 801 var context = walker.state; 802 var go = true; 803 if (ast) { 804 if (ast.nodeType == NodeType.List) { 805 var list = ast; 806 list.enclosingScope = context.scopeChain.scope; 807 } 808 else if (ast.nodeType == NodeType.ModuleDeclaration) { 809 preAssignModuleScopes(ast, context); 810 } 811 else if (ast.nodeType == NodeType.ClassDeclaration) { 812 preAssignClassScopes(ast, context); 813 } 814 else if (ast.nodeType == NodeType.InterfaceDeclaration) { 815 preAssignInterfaceScopes(ast, context); 816 } 817 else if (ast.nodeType == NodeType.With) { 818 preAssignWithScopes(ast, context); 819 } 820 else if (ast.nodeType == NodeType.FuncDecl) { 821 preAssignFuncDeclScopes(ast, context); 822 } 823 else if (ast.nodeType == NodeType.Catch) { 824 preAssignCatchScopes(ast, context); 825 } 826 else if (ast.nodeType == NodeType.TypeRef) { 827 go = false; 828 } 829 } 830 walker.options.goChildren = go; 831 return ast; 832 } 833 TypeScript.preAssignScopes = preAssignScopes; 834 function postAssignScopes(ast, parent, walker) { 835 var context = walker.state; 836 var go = true; 837 if (ast) { 838 if (ast.nodeType == NodeType.ModuleDeclaration) { 839 var prevModDecl = ast; 840 popAssignScope(context); 841 context.modDeclChain.pop(); 842 if (context.modDeclChain.length >= 1) { 843 context.typeFlow.checker.currentModDecl = context.modDeclChain[context.modDeclChain.length - 1]; 844 } 845 } 846 else if (ast.nodeType == NodeType.ClassDeclaration) { 847 popAssignScope(context); 848 } 849 else if (ast.nodeType == NodeType.InterfaceDeclaration) { 850 popAssignScope(context); 851 } 852 else if (ast.nodeType == NodeType.With) { 853 popAssignScope(context); 854 } 855 else if (ast.nodeType == NodeType.FuncDecl) { 856 var funcDecl = ast; 857 if ((!funcDecl.isConstructor || hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) && !funcDecl.isOverload) { 858 popAssignScope(context); 859 } 860 } 861 else if (ast.nodeType == NodeType.Catch) { 862 var catchBlock = ast; 863 if (catchBlock.param) { 864 popAssignScope(context); 865 } 866 } 867 else { 868 go = false; 869 } 870 } 871 walker.options.goChildren = go; 872 return ast; 873 } 874 TypeScript.postAssignScopes = postAssignScopes; 875})(TypeScript || (TypeScript = {})); 876