• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//// [parserRealSource6.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    export class TypeCollectionContext {
9        public script: Script = null;
10
11        constructor (public scopeChain: ScopeChain, public checker: TypeChecker) {
12        }
13    }
14
15    export class MemberScopeContext {
16        public type: Type = null;
17        public ast: AST = null;
18        public scope: SymbolScope;
19        public options = new AstWalkOptions();
20
21        constructor (public flow: TypeFlow, public pos: number, public matchFlag: ASTFlags) {
22        }
23    }
24
25    export class EnclosingScopeContext {
26
27        public scopeGetter: () => SymbolScope = null;
28        public objectLiteralScopeGetter: () => SymbolScope = null;
29        public scopeStartAST: AST = null;
30        public skipNextFuncDeclForClass = false;
31        public deepestModuleDecl: ModuleDeclaration = null;
32        public enclosingClassDecl: TypeDeclaration = null;
33        public enclosingObjectLit: UnaryExpression = null;
34        public publicsOnly = true;
35        public useFullAst = false;
36        private scriptFragment: Script;
37
38        constructor (public logger: ILogger,
39                    public script: Script,
40                    public text: ISourceText,
41                    public pos: number,
42                    public isMemberCompletion: boolean) {
43        }
44
45        public getScope(): SymbolScope {
46            return this.scopeGetter();
47        }
48
49        public getObjectLiteralScope(): SymbolScope {
50            return this.objectLiteralScopeGetter();
51        }
52
53        public getScopeAST() {
54            return this.scopeStartAST;
55        }
56
57        public getScopePosition() {
58            return this.scopeStartAST.minChar;
59        }
60
61        public getScriptFragmentStartAST(): AST {
62            return this.scopeStartAST;
63        }
64
65        public getScriptFragmentPosition(): number {
66            return this.getScriptFragmentStartAST().minChar;
67        }
68
69        public getScriptFragment(): Script {
70            if (this.scriptFragment == null) {
71                var ast = this.getScriptFragmentStartAST();
72                var minChar = ast.minChar;
73                var limChar = (this.isMemberCompletion ? this.pos : this.pos + 1);
74                this.scriptFragment = TypeScript.quickParse(this.logger, ast, this.text, minChar, limChar, null/*errorCapture*/).Script;
75            }
76            return this.scriptFragment;
77        }
78    }
79
80    export function preFindMemberScope(ast: AST, parent: AST, walker: IAstWalker) {
81        var memScope: MemberScopeContext = walker.state;
82        if (hasFlag(ast.flags, memScope.matchFlag) && ((memScope.pos < 0) || (memScope.pos == ast.limChar))) {
83            memScope.ast = ast;
84            if ((ast.type == null) && (memScope.pos >= 0)) {
85                memScope.flow.inScopeTypeCheck(ast, memScope.scope);
86            }
87            memScope.type = ast.type;
88            memScope.options.stopWalk();
89        }
90        return ast;
91    }
92
93    export function pushTypeCollectionScope(container: Symbol,
94        valueMembers: ScopedMembers,
95        ambientValueMembers: ScopedMembers,
96        enclosedTypes: ScopedMembers,
97        ambientEnclosedTypes: ScopedMembers,
98        context: TypeCollectionContext,
99        thisType: Type,
100        classType: Type,
101        moduleDecl: ModuleDeclaration) {
102        var builder = new SymbolScopeBuilder(valueMembers, ambientValueMembers, enclosedTypes, ambientEnclosedTypes, null, container);
103        var chain: ScopeChain = new ScopeChain(container, context.scopeChain, builder);
104        chain.thisType = thisType;
105        chain.classType = classType;
106        chain.moduleDecl = moduleDecl;
107        context.scopeChain = chain;
108    }
109
110    export function popTypeCollectionScope(context: TypeCollectionContext) {
111        context.scopeChain = context.scopeChain.previous;
112    }
113
114    export function preFindEnclosingScope(ast: AST, parent: AST, walker: IAstWalker) {
115        var context: EnclosingScopeContext = walker.state;
116        var minChar = ast.minChar;
117        var limChar = ast.limChar;
118
119        // Account for the fact completion list may be called at the end of a file which
120        // is has not been fully re-parsed yet.
121        if (ast.nodeType == NodeType.Script && context.pos > limChar)
122            limChar = context.pos;
123
124        if ((minChar <= context.pos) &&
125            (limChar >= context.pos)) {
126            switch (ast.nodeType) {
127                case NodeType.Script:
128                    var script = <Script>ast;
129                    context.scopeGetter = function () {
130                        return script.bod === null ? null : script.bod.enclosingScope;
131                    };
132                    context.scopeStartAST = script;
133                    break;
134
135                case NodeType.ClassDeclaration:
136                    context.scopeGetter = function () {
137                        return (ast.type === null || ast.type.instanceType.containedScope === null) ? null : ast.type.instanceType.containedScope;
138                    };
139                    context.scopeStartAST = ast;
140                    context.enclosingClassDecl = <TypeDeclaration>ast;
141                    break;
142
143                case NodeType.ObjectLit:
144                    var objectLit = <UnaryExpression>ast;
145                    // Only consider target-typed object literals
146                    if (objectLit.targetType) {
147                        context.scopeGetter = function () {
148                            return objectLit.targetType.containedScope;
149                        };
150                        context.objectLiteralScopeGetter = function () {
151                            return objectLit.targetType.memberScope;
152                        }
153                        context.enclosingObjectLit = objectLit;
154                    }
155                    break;
156
157                case NodeType.ModuleDeclaration:
158                    context.deepestModuleDecl = <ModuleDeclaration>ast;
159                    context.scopeGetter = function () {
160                        return ast.type === null ? null : ast.type.containedScope;
161                    };
162                    context.scopeStartAST = ast;
163                    break;
164
165                case NodeType.InterfaceDeclaration:
166                    context.scopeGetter = function () {
167                        return (ast.type === null) ? null : ast.type.containedScope;
168                    };
169                    context.scopeStartAST = ast;
170                    break;
171
172                case NodeType.FuncDecl: {
173                    var funcDecl = <FuncDecl>ast;
174                    if (context.skipNextFuncDeclForClass) {
175                        context.skipNextFuncDeclForClass = false;
176                    }
177                    else {
178                        context.scopeGetter = function () {
179                            // The scope of a class constructor is hidden somewhere we don't expect :-S
180                            if (funcDecl.isConstructor && hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) {
181                                if (ast.type && ast.type.enclosingType) {
182                                    return ast.type.enclosingType.constructorScope;
183                                }
184                            }
185
186                            if (funcDecl.scopeType) {
187                                return funcDecl.scopeType.containedScope;
188                            }
189
190                            if (funcDecl.type) {
191                                return funcDecl.type.containedScope;
192                            }
193                            return null;
194                        };
195                        context.scopeStartAST = ast;
196                    }
197                }
198                    break;
199            }
200            walker.options.goChildren = true;
201        }
202        else {
203            walker.options.goChildren = false;
204        }
205        return ast;
206    }
207
208    //
209    // Find the enclosing scope context from a position inside a script AST.
210    // The "scopeStartAST" of the returned scope is always valid.
211    // Return "null" if the enclosing scope can't be found.
212    //
213    export function findEnclosingScopeAt(logger: ILogger, script: Script, text: ISourceText, pos: number, isMemberCompletion: boolean): EnclosingScopeContext {
214        var context = new EnclosingScopeContext(logger, script, text, pos, isMemberCompletion);
215
216        TypeScript.getAstWalkerFactory().walk(script, preFindEnclosingScope, null, null, context);
217
218        if (context.scopeStartAST === null)
219            return null;
220        return context;
221    }
222}
223
224//// [parserRealSource6.js]
225// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
226// See LICENSE.txt in the project root for complete license information.
227///<reference path='typescript.ts' />
228var TypeScript;
229(function (TypeScript) {
230    var TypeCollectionContext = /** @class */ (function () {
231        function TypeCollectionContext(scopeChain, checker) {
232            this.scopeChain = scopeChain;
233            this.checker = checker;
234            this.script = null;
235        }
236        return TypeCollectionContext;
237    }());
238    TypeScript.TypeCollectionContext = TypeCollectionContext;
239    var MemberScopeContext = /** @class */ (function () {
240        function MemberScopeContext(flow, pos, matchFlag) {
241            this.flow = flow;
242            this.pos = pos;
243            this.matchFlag = matchFlag;
244            this.type = null;
245            this.ast = null;
246            this.options = new AstWalkOptions();
247        }
248        return MemberScopeContext;
249    }());
250    TypeScript.MemberScopeContext = MemberScopeContext;
251    var EnclosingScopeContext = /** @class */ (function () {
252        function EnclosingScopeContext(logger, script, text, pos, isMemberCompletion) {
253            this.logger = logger;
254            this.script = script;
255            this.text = text;
256            this.pos = pos;
257            this.isMemberCompletion = isMemberCompletion;
258            this.scopeGetter = null;
259            this.objectLiteralScopeGetter = null;
260            this.scopeStartAST = null;
261            this.skipNextFuncDeclForClass = false;
262            this.deepestModuleDecl = null;
263            this.enclosingClassDecl = null;
264            this.enclosingObjectLit = null;
265            this.publicsOnly = true;
266            this.useFullAst = false;
267        }
268        EnclosingScopeContext.prototype.getScope = function () {
269            return this.scopeGetter();
270        };
271        EnclosingScopeContext.prototype.getObjectLiteralScope = function () {
272            return this.objectLiteralScopeGetter();
273        };
274        EnclosingScopeContext.prototype.getScopeAST = function () {
275            return this.scopeStartAST;
276        };
277        EnclosingScopeContext.prototype.getScopePosition = function () {
278            return this.scopeStartAST.minChar;
279        };
280        EnclosingScopeContext.prototype.getScriptFragmentStartAST = function () {
281            return this.scopeStartAST;
282        };
283        EnclosingScopeContext.prototype.getScriptFragmentPosition = function () {
284            return this.getScriptFragmentStartAST().minChar;
285        };
286        EnclosingScopeContext.prototype.getScriptFragment = function () {
287            if (this.scriptFragment == null) {
288                var ast = this.getScriptFragmentStartAST();
289                var minChar = ast.minChar;
290                var limChar = (this.isMemberCompletion ? this.pos : this.pos + 1);
291                this.scriptFragment = TypeScript.quickParse(this.logger, ast, this.text, minChar, limChar, null /*errorCapture*/).Script;
292            }
293            return this.scriptFragment;
294        };
295        return EnclosingScopeContext;
296    }());
297    TypeScript.EnclosingScopeContext = EnclosingScopeContext;
298    function preFindMemberScope(ast, parent, walker) {
299        var memScope = walker.state;
300        if (hasFlag(ast.flags, memScope.matchFlag) && ((memScope.pos < 0) || (memScope.pos == ast.limChar))) {
301            memScope.ast = ast;
302            if ((ast.type == null) && (memScope.pos >= 0)) {
303                memScope.flow.inScopeTypeCheck(ast, memScope.scope);
304            }
305            memScope.type = ast.type;
306            memScope.options.stopWalk();
307        }
308        return ast;
309    }
310    TypeScript.preFindMemberScope = preFindMemberScope;
311    function pushTypeCollectionScope(container, valueMembers, ambientValueMembers, enclosedTypes, ambientEnclosedTypes, context, thisType, classType, moduleDecl) {
312        var builder = new SymbolScopeBuilder(valueMembers, ambientValueMembers, enclosedTypes, ambientEnclosedTypes, null, container);
313        var chain = new ScopeChain(container, context.scopeChain, builder);
314        chain.thisType = thisType;
315        chain.classType = classType;
316        chain.moduleDecl = moduleDecl;
317        context.scopeChain = chain;
318    }
319    TypeScript.pushTypeCollectionScope = pushTypeCollectionScope;
320    function popTypeCollectionScope(context) {
321        context.scopeChain = context.scopeChain.previous;
322    }
323    TypeScript.popTypeCollectionScope = popTypeCollectionScope;
324    function preFindEnclosingScope(ast, parent, walker) {
325        var context = walker.state;
326        var minChar = ast.minChar;
327        var limChar = ast.limChar;
328        // Account for the fact completion list may be called at the end of a file which
329        // is has not been fully re-parsed yet.
330        if (ast.nodeType == NodeType.Script && context.pos > limChar)
331            limChar = context.pos;
332        if ((minChar <= context.pos) &&
333            (limChar >= context.pos)) {
334            switch (ast.nodeType) {
335                case NodeType.Script:
336                    var script = ast;
337                    context.scopeGetter = function () {
338                        return script.bod === null ? null : script.bod.enclosingScope;
339                    };
340                    context.scopeStartAST = script;
341                    break;
342                case NodeType.ClassDeclaration:
343                    context.scopeGetter = function () {
344                        return (ast.type === null || ast.type.instanceType.containedScope === null) ? null : ast.type.instanceType.containedScope;
345                    };
346                    context.scopeStartAST = ast;
347                    context.enclosingClassDecl = ast;
348                    break;
349                case NodeType.ObjectLit:
350                    var objectLit = ast;
351                    // Only consider target-typed object literals
352                    if (objectLit.targetType) {
353                        context.scopeGetter = function () {
354                            return objectLit.targetType.containedScope;
355                        };
356                        context.objectLiteralScopeGetter = function () {
357                            return objectLit.targetType.memberScope;
358                        };
359                        context.enclosingObjectLit = objectLit;
360                    }
361                    break;
362                case NodeType.ModuleDeclaration:
363                    context.deepestModuleDecl = ast;
364                    context.scopeGetter = function () {
365                        return ast.type === null ? null : ast.type.containedScope;
366                    };
367                    context.scopeStartAST = ast;
368                    break;
369                case NodeType.InterfaceDeclaration:
370                    context.scopeGetter = function () {
371                        return (ast.type === null) ? null : ast.type.containedScope;
372                    };
373                    context.scopeStartAST = ast;
374                    break;
375                case NodeType.FuncDecl:
376                    {
377                        var funcDecl = ast;
378                        if (context.skipNextFuncDeclForClass) {
379                            context.skipNextFuncDeclForClass = false;
380                        }
381                        else {
382                            context.scopeGetter = function () {
383                                // The scope of a class constructor is hidden somewhere we don't expect :-S
384                                if (funcDecl.isConstructor && hasFlag(funcDecl.fncFlags, FncFlags.ClassMethod)) {
385                                    if (ast.type && ast.type.enclosingType) {
386                                        return ast.type.enclosingType.constructorScope;
387                                    }
388                                }
389                                if (funcDecl.scopeType) {
390                                    return funcDecl.scopeType.containedScope;
391                                }
392                                if (funcDecl.type) {
393                                    return funcDecl.type.containedScope;
394                                }
395                                return null;
396                            };
397                            context.scopeStartAST = ast;
398                        }
399                    }
400                    break;
401            }
402            walker.options.goChildren = true;
403        }
404        else {
405            walker.options.goChildren = false;
406        }
407        return ast;
408    }
409    TypeScript.preFindEnclosingScope = preFindEnclosingScope;
410    //
411    // Find the enclosing scope context from a position inside a script AST.
412    // The "scopeStartAST" of the returned scope is always valid.
413    // Return "null" if the enclosing scope can't be found.
414    //
415    function findEnclosingScopeAt(logger, script, text, pos, isMemberCompletion) {
416        var context = new EnclosingScopeContext(logger, script, text, pos, isMemberCompletion);
417        TypeScript.getAstWalkerFactory().walk(script, preFindEnclosingScope, null, null, context);
418        if (context.scopeStartAST === null)
419            return null;
420        return context;
421    }
422    TypeScript.findEnclosingScopeAt = findEnclosingScopeAt;
423})(TypeScript || (TypeScript = {}));
424