Merge ParserContextFlags into NodeFlags

This commit is contained in:
Anders Hejlsberg
2016-01-31 08:45:14 -08:00
parent f0abb86158
commit 83859c0d91
5 changed files with 66 additions and 93 deletions
+8 -8
View File
@@ -2634,7 +2634,7 @@ namespace ts {
// Return the inferred type for a variable, parameter, or property declaration
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type {
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (declaration.parserContextFlags & NodeFlags.JavaScriptFile) {
// If this is a variable in a JavaScript file, then use the JSDoc type (if it has
// one as its type), otherwise fallback to the below standard TS codepaths to
// try to figure it out.
@@ -3981,7 +3981,7 @@ namespace ts {
}
function getTypeParametersFromJSDocTemplate(declaration: SignatureDeclaration): TypeParameter[] {
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (declaration.parserContextFlags & NodeFlags.JavaScriptFile) {
const templateTag = getJSDocTemplateTag(declaration);
if (templateTag) {
return getTypeParametersFromDeclaration(templateTag.typeParameters);
@@ -4015,7 +4015,7 @@ namespace ts {
}
function isOptionalParameter(node: ParameterDeclaration) {
if (node.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (node.parserContextFlags & NodeFlags.JavaScriptFile) {
if (node.type && node.type.kind === SyntaxKind.JSDocOptionalType) {
return true;
}
@@ -4124,7 +4124,7 @@ namespace ts {
returnType = getTypeFromTypeNode(declaration.type);
}
else {
if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (declaration.parserContextFlags & NodeFlags.JavaScriptFile) {
const type = getReturnTypeFromJSDocComment(declaration);
if (type && type !== unknownType) {
returnType = type;
@@ -7183,7 +7183,7 @@ namespace ts {
}
}
if (node.parserContextFlags & ParserContextFlags.Await) {
if (node.parserContextFlags & NodeFlags.Await) {
getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments;
}
}
@@ -10783,7 +10783,7 @@ namespace ts {
function checkAwaitExpression(node: AwaitExpression): Type {
// Grammar checking
if (produceDiagnostics) {
if (!(node.parserContextFlags & ParserContextFlags.Await)) {
if (!(node.parserContextFlags & NodeFlags.Await)) {
grammarErrorOnFirstToken(node, Diagnostics.await_expression_is_only_allowed_within_an_async_function);
}
@@ -11239,7 +11239,7 @@ namespace ts {
function checkYieldExpression(node: YieldExpression): Type {
// Grammar checking
if (produceDiagnostics) {
if (!(node.parserContextFlags & ParserContextFlags.Yield) || isYieldExpressionInClass(node)) {
if (!(node.parserContextFlags & NodeFlags.Yield) || isYieldExpressionInClass(node)) {
grammarErrorOnFirstToken(node, Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
}
@@ -13701,7 +13701,7 @@ namespace ts {
function checkWithStatement(node: WithStatement) {
// Grammar checking for withStatement
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.parserContextFlags & ParserContextFlags.Await) {
if (node.parserContextFlags & NodeFlags.Await) {
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
}
}
+29 -29
View File
@@ -438,7 +438,7 @@ namespace ts {
// Share a single scanner across all calls to parse a source file. This helps speed things
// up by avoiding the cost of creating/compiling scanners over and over again.
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
const disallowInAndDecoratorContext = ParserContextFlags.DisallowIn | ParserContextFlags.Decorator;
const disallowInAndDecoratorContext = NodeFlags.DisallowIn | NodeFlags.Decorator;
// capture constructors in 'initializeState' to avoid null checks
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
@@ -502,7 +502,7 @@ namespace ts {
// Note: it should not be necessary to save/restore these flags during speculative/lookahead
// parsing. These context flags are naturally stored and restored through normal recursive
// descent parsing and unwinding.
let contextFlags: ParserContextFlags;
let contextFlags: NodeFlags;
// Whether or not we've had a parse error since creating the last AST node. If we have
// encountered an error, it will be stored on the next AST node we create. Parse errors
@@ -562,7 +562,7 @@ namespace ts {
identifierCount = 0;
nodeCount = 0;
contextFlags = isJavaScriptFile ? ParserContextFlags.JavaScriptFile : ParserContextFlags.None;
contextFlags = isJavaScriptFile ? NodeFlags.JavaScriptFile : NodeFlags.None;
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
@@ -588,8 +588,8 @@ namespace ts {
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile {
sourceFile = createSourceFile(fileName, languageVersion);
if (contextFlags & ParserContextFlags.JavaScriptFile) {
sourceFile.parserContextFlags = ParserContextFlags.JavaScriptFile;
if (contextFlags & NodeFlags.JavaScriptFile) {
sourceFile.parserContextFlags = NodeFlags.JavaScriptFile;
}
// Prime the scanner.
@@ -616,7 +616,7 @@ namespace ts {
function addJSDocComment<T extends Node>(node: T): T {
if (contextFlags & ParserContextFlags.JavaScriptFile) {
if (contextFlags & NodeFlags.JavaScriptFile) {
const comments = getLeadingCommentRangesOfNode(node, sourceFile);
if (comments) {
for (const comment of comments) {
@@ -672,7 +672,7 @@ namespace ts {
return sourceFile;
}
function setContextFlag(val: boolean, flag: ParserContextFlags) {
function setContextFlag(val: boolean, flag: NodeFlags) {
if (val) {
contextFlags |= flag;
}
@@ -682,22 +682,22 @@ namespace ts {
}
function setDisallowInContext(val: boolean) {
setContextFlag(val, ParserContextFlags.DisallowIn);
setContextFlag(val, NodeFlags.DisallowIn);
}
function setYieldContext(val: boolean) {
setContextFlag(val, ParserContextFlags.Yield);
setContextFlag(val, NodeFlags.Yield);
}
function setDecoratorContext(val: boolean) {
setContextFlag(val, ParserContextFlags.Decorator);
setContextFlag(val, NodeFlags.Decorator);
}
function setAwaitContext(val: boolean) {
setContextFlag(val, ParserContextFlags.Await);
setContextFlag(val, NodeFlags.Await);
}
function doOutsideOfContext<T>(context: ParserContextFlags, func: () => T): T {
function doOutsideOfContext<T>(context: NodeFlags, func: () => T): T {
// contextFlagsToClear will contain only the context flags that are
// currently set that we need to temporarily clear
// We don't just blindly reset to the previous flags to ensure
@@ -718,7 +718,7 @@ namespace ts {
return func();
}
function doInsideOfContext<T>(context: ParserContextFlags, func: () => T): T {
function doInsideOfContext<T>(context: NodeFlags, func: () => T): T {
// contextFlagsToSet will contain only the context flags that
// are not currently set that we need to temporarily enable.
// We don't just blindly reset to the previous flags to ensure
@@ -740,51 +740,51 @@ namespace ts {
}
function allowInAnd<T>(func: () => T): T {
return doOutsideOfContext(ParserContextFlags.DisallowIn, func);
return doOutsideOfContext(NodeFlags.DisallowIn, func);
}
function disallowInAnd<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.DisallowIn, func);
return doInsideOfContext(NodeFlags.DisallowIn, func);
}
function doInYieldContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Yield, func);
return doInsideOfContext(NodeFlags.Yield, func);
}
function doInDecoratorContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Decorator, func);
return doInsideOfContext(NodeFlags.Decorator, func);
}
function doInAwaitContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Await, func);
return doInsideOfContext(NodeFlags.Await, func);
}
function doOutsideOfAwaitContext<T>(func: () => T): T {
return doOutsideOfContext(ParserContextFlags.Await, func);
return doOutsideOfContext(NodeFlags.Await, func);
}
function doInYieldAndAwaitContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Yield | ParserContextFlags.Await, func);
return doInsideOfContext(NodeFlags.Yield | NodeFlags.Await, func);
}
function inContext(flags: ParserContextFlags) {
function inContext(flags: NodeFlags) {
return (contextFlags & flags) !== 0;
}
function inYieldContext() {
return inContext(ParserContextFlags.Yield);
return inContext(NodeFlags.Yield);
}
function inDisallowInContext() {
return inContext(ParserContextFlags.DisallowIn);
return inContext(NodeFlags.DisallowIn);
}
function inDecoratorContext() {
return inContext(ParserContextFlags.Decorator);
return inContext(NodeFlags.Decorator);
}
function inAwaitContext() {
return inContext(ParserContextFlags.Await);
return inContext(NodeFlags.Await);
}
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void {
@@ -1004,7 +1004,7 @@ namespace ts {
// flag so that we don't mark any subsequent nodes.
if (parseErrorBeforeNextFinishedNode) {
parseErrorBeforeNextFinishedNode = false;
node.parserContextFlags |= ParserContextFlags.ThisNodeHasError;
node.parserContextFlags |= NodeFlags.ThisNodeHasError;
}
return node;
@@ -1453,7 +1453,7 @@ namespace ts {
// differently depending on what mode it is in.
//
// This also applies to all our other context flags as well.
const nodeContextFlags = node.parserContextFlags & ParserContextFlags.ParserGeneratedFlags;
const nodeContextFlags = node.parserContextFlags & NodeFlags.ParserGeneratedFlags;
if (nodeContextFlags !== contextFlags) {
return undefined;
}
@@ -2512,7 +2512,7 @@ namespace ts {
function parseType(): TypeNode {
// The rules about 'yield' only apply to actual code/expression contexts. They don't
// apply to 'type' contexts. So we disable these parameters here before moving on.
return doOutsideOfContext(ParserContextFlags.TypeExcludesFlags, parseTypeWorker);
return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseTypeWorker);
}
function parseTypeWorker(): TypeNode {
@@ -4785,7 +4785,7 @@ namespace ts {
// The checker may still error in the static case to explicitly disallow the yield expression.
property.initializer = modifiers && modifiers.flags & NodeFlags.Static
? allowInAnd(parseNonParameterInitializer)
: doOutsideOfContext(ParserContextFlags.Yield | ParserContextFlags.DisallowIn, parseNonParameterInitializer);
: doOutsideOfContext(NodeFlags.Yield | NodeFlags.DisallowIn, parseNonParameterInitializer);
parseSemicolon();
return finishNode(property);
+21 -48
View File
@@ -381,18 +381,26 @@ namespace ts {
Abstract = 1 << 7, // Class/Method/ConstructSignature
Async = 1 << 8, // Property/Method/Function
Default = 1 << 9, // Function/Class (export default declaration)
Let = 1 << 13, // Variable declaration
Const = 1 << 14, // Variable declaration
Namespace = 1 << 16, // Namespace declaration
ExportContext = 1 << 17, // Export context (initialized by binding)
ContainsThis = 1 << 18, // Interface contains references to "this"
HasImplicitReturn = 1 << 19, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 20, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 21, // Set if module declaration is an augmentation for the global scope
HasClassExtends = 1 << 22, // If the file has a non-ambient class with an extends clause in ES5 or lower (initialized by binding)
HasDecorators = 1 << 23, // If the file has decorators (initialized by binding)
HasParamDecorators = 1 << 24, // If the file has parameter decorators (initialized by binding)
HasAsyncFunctions = 1 << 25, // If the file has async functions (initialized by binding)
Let = 1 << 10, // Variable declaration
Const = 1 << 11, // Variable declaration
Namespace = 1 << 12, // Namespace declaration
ExportContext = 1 << 13, // Export context (initialized by binding)
ContainsThis = 1 << 14, // Interface contains references to "this"
HasImplicitReturn = 1 << 15, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 16, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 17, // Set if module declaration is an augmentation for the global scope
HasClassExtends = 1 << 18, // If the file has a non-ambient class with an extends clause in ES5 or lower (initialized by binding)
HasDecorators = 1 << 19, // If the file has decorators (initialized by binding)
HasParamDecorators = 1 << 20, // If the file has parameter decorators (initialized by binding)
HasAsyncFunctions = 1 << 21, // If the file has async functions (initialized by binding)
DisallowIn = 1 << 22, // If node was parsed in a context where 'in-expressions' are not allowed
Yield = 1 << 23, // If node was parsed in the 'yield' context created when parsing a generator
Decorator = 1 << 24, // If node was parsed as part of a decorator
Await = 1 << 25, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 26, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 27, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 28, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 29, // If we've computed data from children and cached it in this node
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
AccessibilityModifier = Public | Private | Protected,
@@ -400,47 +408,12 @@ namespace ts {
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions,
}
/* @internal */
export const enum ParserContextFlags {
None = 0,
// If this node was parsed in a context where 'in-expressions' are not allowed.
DisallowIn = 1 << 0,
// If this node was parsed in the 'yield' context created when parsing a generator.
Yield = 1 << 1,
// If this node was parsed as part of a decorator
Decorator = 1 << 2,
// If this node was parsed in the 'await' context created when parsing an async function.
Await = 1 << 3,
// If the parser encountered an error when parsing the code that created this node. Note
// the parser only sets this directly on the node it creates right after encountering the
// error.
ThisNodeHasError = 1 << 4,
// This node was parsed in a JavaScript file and can be processed differently. For example
// its type can be specified usign a JSDoc comment.
JavaScriptFile = 1 << 5,
// Context flags set directly by the parser.
ParserGeneratedFlags = DisallowIn | Yield | Decorator | ThisNodeHasError | Await,
// Exclude these flags when parsing a Type
TypeExcludesFlags = Yield | Await,
// Context flags computed by aggregating child flags upwards.
// Used during incremental parsing to determine if this node or any of its children had an
// error. Computed only once and then cached.
ThisNodeOrAnySubNodesHasError = 1 << 6,
// Used to know if we've computed data from children and cached it in this node.
HasAggregatedChildData = 1 << 7
}
export const enum JsxFlags {
@@ -470,7 +443,7 @@ namespace ts {
flags: NodeFlags;
// Specific context the parser was in when this node was created. Normally undefined.
// Only set when the parser was in some interesting context (like async/yield).
/* @internal */ parserContextFlags?: ParserContextFlags;
/* @internal */ parserContextFlags?: NodeFlags;
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
+7 -7
View File
@@ -121,26 +121,26 @@ namespace ts {
// Returns true if this node contains a parse error anywhere underneath it.
export function containsParseError(node: Node): boolean {
aggregateChildData(node);
return (node.parserContextFlags & ParserContextFlags.ThisNodeOrAnySubNodesHasError) !== 0;
return (node.parserContextFlags & NodeFlags.ThisNodeOrAnySubNodesHasError) !== 0;
}
function aggregateChildData(node: Node): void {
if (!(node.parserContextFlags & ParserContextFlags.HasAggregatedChildData)) {
if (!(node.parserContextFlags & NodeFlags.HasAggregatedChildData)) {
// A node is considered to contain a parse error if:
// a) the parser explicitly marked that it had an error
// b) any of it's children reported that it had an error.
const thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & ParserContextFlags.ThisNodeHasError) !== 0) ||
const thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & NodeFlags.ThisNodeHasError) !== 0) ||
forEachChild(node, containsParseError);
// If so, mark ourselves accordingly.
if (thisNodeOrAnySubNodesHasError) {
node.parserContextFlags |= ParserContextFlags.ThisNodeOrAnySubNodesHasError;
node.parserContextFlags |= NodeFlags.ThisNodeOrAnySubNodesHasError;
}
// Also mark that we've propogated the child information to this node. This way we can
// always consult the bit directly on this node without needing to check its children
// again.
node.parserContextFlags |= ParserContextFlags.HasAggregatedChildData;
node.parserContextFlags |= NodeFlags.HasAggregatedChildData;
}
}
@@ -1078,7 +1078,7 @@ namespace ts {
}
export function isInJavaScriptFile(node: Node): boolean {
return node && !!(node.parserContextFlags & ParserContextFlags.JavaScriptFile);
return node && !!(node.parserContextFlags & NodeFlags.JavaScriptFile);
}
/**
@@ -1266,7 +1266,7 @@ namespace ts {
export function isRestParameter(node: ParameterDeclaration) {
if (node) {
if (node.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (node.parserContextFlags & NodeFlags.JavaScriptFile) {
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
return true;
}
+1 -1
View File
@@ -284,7 +284,7 @@ namespace Utils {
// Clear the flag that are produced by aggregating child values.. That is ephemeral
// data we don't care about in the dump. We only care what the parser set directly
// on the ast.
let value = n.parserContextFlags & ts.ParserContextFlags.ParserGeneratedFlags;
let value = n.parserContextFlags & ts.NodeFlags.ParserGeneratedFlags;
if (value) {
o[propertyName] = getParserContextFlagName(value);
}