in Public/Src/FrontEnd/TypeScript.Net/TypeScript.Net/TypeScriptImpl/checker.ts [15608:15828]
function checkGrammarModifiers(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Constructor:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.ExportDeclaration:
case SyntaxKind.ExportAssignment:
case SyntaxKind.Parameter:
break;
case SyntaxKind.FunctionDeclaration:
if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== SyntaxKind.AsyncKeyword) &&
node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.VariableStatement:
case SyntaxKind.TypeAliasDeclaration:
if (node.modifiers && node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
break;
case SyntaxKind.EnumDeclaration:
if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== SyntaxKind.ConstKeyword) &&
node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
break;
default:
return false;
}
if (!node.modifiers) {
return;
}
let lastStatic: Node, lastPrivate: Node, lastProtected: Node, lastDeclare: Node, lastAsync: Node;
let flags = 0;
for (const modifier of node.modifiers) {
switch (modifier.kind) {
case SyntaxKind.ConstKeyword:
if (node.kind !== SyntaxKind.EnumDeclaration && node.parent.kind === SyntaxKind.ClassDeclaration) {
return grammarErrorOnNode(node, Diagnostics.A_class_member_cannot_have_the_0_keyword, tokenToString(SyntaxKind.ConstKeyword));
}
break;
case SyntaxKind.PublicKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.PrivateKeyword:
let text: string;
if (modifier.kind === SyntaxKind.PublicKeyword) {
text = "public";
}
else if (modifier.kind === SyntaxKind.ProtectedKeyword) {
text = "protected";
lastProtected = modifier;
}
else {
text = "private";
lastPrivate = modifier;
}
if (flags & NodeFlags.AccessibilityModifier) {
return grammarErrorOnNode(modifier, Diagnostics.Accessibility_modifier_already_seen);
}
else if (flags & NodeFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_element, text);
}
else if (flags & NodeFlags.Abstract) {
if (modifier.kind === SyntaxKind.PrivateKeyword) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
}
else {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
}
}
flags |= modifierToFlag(modifier.kind);
break;
case SyntaxKind.StaticKeyword:
if (flags & NodeFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_element, "static");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
}
else if (flags & NodeFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
}
flags |= NodeFlags.Static;
lastStatic = modifier;
break;
case SyntaxKind.ExportKeyword:
if (flags & NodeFlags.Export) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "export");
}
else if (flags & NodeFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
}
else if (flags & NodeFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
}
flags |= NodeFlags.Export;
break;
case SyntaxKind.DeclareKeyword:
if (flags & NodeFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
}
else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) {
return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
}
flags |= NodeFlags.Ambient;
lastDeclare = modifier;
break;
case SyntaxKind.AbstractKeyword:
if (flags & NodeFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract");
}
if (node.kind !== SyntaxKind.ClassDeclaration) {
if (node.kind !== SyntaxKind.MethodDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_or_method_declaration);
}
if (!(node.parent.kind === SyntaxKind.ClassDeclaration && node.parent.flags & NodeFlags.Abstract)) {
return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
}
if (flags & NodeFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
}
if (flags & NodeFlags.Private) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
}
}
flags |= NodeFlags.Abstract;
break;
case SyntaxKind.AsyncKeyword:
if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
}
else if (flags & NodeFlags.Ambient || isInAmbientContext(node.parent)) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
}
flags |= NodeFlags.Async;
lastAsync = modifier;
break;
}
}
if (node.kind === SyntaxKind.Constructor) {
if (flags & NodeFlags.Static) {
return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
}
if (flags & NodeFlags.Abstract) {
return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract");
}
else if (flags & NodeFlags.Protected) {
return grammarErrorOnNode(lastProtected, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "protected");
}
else if (flags & NodeFlags.Private) {
return grammarErrorOnNode(lastPrivate, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
}
return;
}
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) {
return grammarErrorOnNode(lastDeclare, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
}
else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.AccessibilityModifier) && isBindingPattern((<ParameterDeclaration>node).name)) {
return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_a_binding_pattern);
}
if (flags & NodeFlags.Async) {
return checkGrammarAsyncModifier(node, lastAsync);
}
}