Adding SyntaxKind.ClassExpression in a bunch of places

This commit is contained in:
Anders Hejlsberg
2015-06-17 17:11:42 -07:00
parent 247d5820dd
commit 0fe60498d7
3 changed files with 49 additions and 79 deletions

View File

@@ -630,7 +630,7 @@ namespace ts {
function getStrictModeIdentifierMessage(node: Node) {
// Provide specialized messages to help the user understand why we think they're in
// strict mode.
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
if (getContainingClass(node)) {
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
}
@@ -688,7 +688,7 @@ namespace ts {
function getStrictModeEvalOrArgumentsMessage(node: Node) {
// Provide specialized messages to help the user understand why we think they're in
// strict mode.
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
if (getContainingClass(node)) {
return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
}
@@ -1031,7 +1031,7 @@ namespace ts {
// containing class.
if (node.flags & NodeFlags.AccessibilityModifier &&
node.parent.kind === SyntaxKind.Constructor &&
(node.parent.parent.kind === SyntaxKind.ClassDeclaration || node.parent.parent.kind === SyntaxKind.ClassExpression)) {
isClassLike(node.parent.parent)) {
let classDeclaration = <ClassLikeDeclaration>node.parent.parent;
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);

View File

@@ -386,8 +386,8 @@ namespace ts {
// local variables of the constructor. This effectively means that entities from outer scopes
// by the same name as a constructor parameter or local variable are inaccessible
// in initializer expressions for instance member variables.
if (location.parent.kind === SyntaxKind.ClassDeclaration && !(location.flags & NodeFlags.Static)) {
let ctor = findConstructorDeclaration(<ClassDeclaration>location.parent);
if (isClassLike(location.parent) && !(location.flags & NodeFlags.Static)) {
let ctor = findConstructorDeclaration(<ClassLikeDeclaration>location.parent);
if (ctor && ctor.locals) {
if (getSymbol(ctor.locals, name, meaning & SymbolFlags.Value)) {
// Remember the property node, it will be used later to report appropriate error
@@ -397,6 +397,7 @@ namespace ts {
}
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & SymbolFlags.Type)) {
if (lastLocation && lastLocation.flags & NodeFlags.Static) {
@@ -420,7 +421,7 @@ namespace ts {
//
case SyntaxKind.ComputedPropertyName:
grandparent = location.parent.parent;
if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
// A reference to this grandparent's type parameters would be an error
if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) {
error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
@@ -1009,7 +1010,7 @@ namespace ts {
return false;
}
function findConstructorDeclaration(node: ClassDeclaration): ConstructorDeclaration {
function findConstructorDeclaration(node: ClassLikeDeclaration): ConstructorDeclaration {
let members = node.members;
for (let member of members) {
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
@@ -2562,10 +2563,10 @@ namespace ts {
if (!node) {
return typeParameters;
}
if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.FunctionDeclaration ||
node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.MethodDeclaration ||
node.kind === SyntaxKind.ArrowFunction) {
let declarations = (<ClassDeclaration | FunctionLikeDeclaration>node).typeParameters;
if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression ||
node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression ||
node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.ArrowFunction) {
let declarations = (<ClassLikeDeclaration | FunctionLikeDeclaration>node).typeParameters;
if (declarations) {
return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations);
}
@@ -2575,8 +2576,8 @@ namespace ts {
// The outer type parameters are those defined by enclosing generic classes, methods, or functions.
function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] {
var kind = symbol.flags & SymbolFlags.Class ? SyntaxKind.ClassDeclaration : SyntaxKind.InterfaceDeclaration;
return appendOuterTypeParameters(undefined, getDeclarationOfKind(symbol, kind));
var declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
return appendOuterTypeParameters(undefined, declaration);
}
// The local type parameters are the combined set of type parameters from all declarations of the class,
@@ -2584,7 +2585,8 @@ namespace ts {
function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] {
let result: TypeParameter[];
for (let node of symbol.declarations) {
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) {
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration ||
node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.TypeAliasDeclaration) {
let declaration = <InterfaceDeclaration | TypeAliasDeclaration>node;
if (declaration.typeParameters) {
result = appendTypeParameters(result, declaration.typeParameters);
@@ -5884,9 +5886,9 @@ namespace ts {
}
function captureLexicalThis(node: Node, container: Node): void {
let classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined;
getNodeLinks(node).flags |= NodeCheckFlags.LexicalThis;
if (container.kind === SyntaxKind.PropertyDeclaration || container.kind === SyntaxKind.Constructor) {
let classNode = container.parent;
getNodeLinks(classNode).flags |= NodeCheckFlags.CaptureThis;
}
else {
@@ -5939,7 +5941,7 @@ namespace ts {
captureLexicalThis(node, container);
}
let classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined;
let classNode = isClassLike(container.parent) ? container.parent : undefined;
if (classNode) {
let symbol = getSymbolOfNode(classNode);
return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol);
@@ -5958,7 +5960,7 @@ namespace ts {
function checkSuperExpression(node: Node): Type {
let isCallExpression = node.parent.kind === SyntaxKind.CallExpression && (<CallExpression>node.parent).expression === node;
let classDeclaration = <ClassDeclaration>getAncestor(node, SyntaxKind.ClassDeclaration);
let classDeclaration = getContainingClass(node);
let classType = classDeclaration && <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration));
let baseClassType = classType && getBaseTypes(classType)[0];
@@ -5993,7 +5995,7 @@ namespace ts {
}
// topmost container must be something that is directly nested in the class declaration
if (container && container.parent && container.parent.kind === SyntaxKind.ClassDeclaration) {
if (container && isClassLike(container.parent)) {
if (container.flags & NodeFlags.Static) {
canUseSuperExpression =
container.kind === SyntaxKind.MethodDeclaration ||
@@ -6652,7 +6654,7 @@ namespace ts {
}
// Property is known to be private or protected at this point
// Get the declaring and enclosing class instance types
let enclosingClassDeclaration = getAncestor(node, SyntaxKind.ClassDeclaration);
let enclosingClassDeclaration = getContainingClass(node);
let enclosingClass = enclosingClassDeclaration ? <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;
let declaringClass = <InterfaceType>getDeclaredTypeOfSymbol(prop.parent);
// Private property is accessible if declaring and enclosing class are the same
@@ -7426,7 +7428,7 @@ namespace ts {
if (superType !== unknownType) {
// In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
// with the type arguments specified in the extends clause.
let baseTypeNode = getClassExtendsHeritageClauseElement(<ClassDeclaration>getAncestor(node, SyntaxKind.ClassDeclaration));
let baseTypeNode = getClassExtendsHeritageClauseElement(getContainingClass(node));
let baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments);
return resolveCall(node, baseConstructors, candidatesOutArray);
}
@@ -8354,7 +8356,7 @@ namespace ts {
if (isFunctionLike(parent) && current === (<FunctionLikeDeclaration>parent).body) {
return false;
}
else if (current.kind === SyntaxKind.ClassDeclaration || current.kind === SyntaxKind.ClassExpression) {
else if (isClassLike(current)) {
return true;
}
@@ -9648,7 +9650,7 @@ namespace ts {
}
// bubble up and find containing type
let enclosingClass = <ClassDeclaration>getAncestor(node, SyntaxKind.ClassDeclaration);
let enclosingClass = getContainingClass(node);
// if containing type was not found or it is ambient - exit (no codegen)
if (!enclosingClass || isInAmbientContext(enclosingClass)) {
return;
@@ -10456,8 +10458,8 @@ namespace ts {
checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number);
});
if (type.flags & TypeFlags.Class && type.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) {
let classDeclaration = <ClassDeclaration>type.symbol.valueDeclaration;
if (type.flags & TypeFlags.Class && isClassLike(type.symbol.valueDeclaration)) {
let classDeclaration = <ClassLikeDeclaration>type.symbol.valueDeclaration;
for (let member of classDeclaration.members) {
// Only process instance properties with computed names here.
// Static properties cannot be in conflict with indexers,
@@ -11727,6 +11729,11 @@ namespace ts {
case SyntaxKind.EnumDeclaration:
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember);
break;
case SyntaxKind.ClassExpression:
if ((<ClassExpression>location).name) {
copySymbol(location.symbol, meaning);
}
// Fall through
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
if (!(memberFlags & NodeFlags.Static)) {
@@ -11766,42 +11773,6 @@ namespace ts {
}
}
}
if (isInsideWithStatementBody(location)) {
// We cannot answer semantic questions within a with block, do not proceed any further
return [];
}
while (location) {
if (location.locals && !isGlobalSourceFile(location)) {
copySymbols(location.locals, meaning);
}
switch (location.kind) {
case SyntaxKind.SourceFile:
if (!isExternalModule(<SourceFile>location)) break;
case SyntaxKind.ModuleDeclaration:
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember);
break;
case SyntaxKind.EnumDeclaration:
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember);
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
if (!(memberFlags & NodeFlags.Static)) {
copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type);
}
break;
case SyntaxKind.FunctionExpression:
if ((<FunctionExpression>location).name) {
copySymbol(location.symbol, meaning);
}
break;
}
memberFlags = location.flags;
location = location.parent;
}
copySymbols(globals, meaning);
return symbolsToArray(symbols);
}
function isTypeDeclarationName(name: Node): boolean {
@@ -13213,7 +13184,7 @@ namespace ts {
}
}
if (node.parent.kind === SyntaxKind.ClassDeclaration) {
if (isClassLike(node.parent)) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) {
return true;
}
@@ -13505,7 +13476,7 @@ namespace ts {
}
function checkGrammarProperty(node: PropertyDeclaration) {
if (node.parent.kind === SyntaxKind.ClassDeclaration) {
if (isClassLike(node.parent)) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) ||
checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
return true;

View File

@@ -542,6 +542,7 @@ namespace ts {
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
// These are not allowed inside a generator now, but eventually they may be allowed
// as local types. Regardless, any yield statements contained within them should be
// skipped in this traversal.
@@ -579,26 +580,15 @@ namespace ts {
return true;
}
}
return false;
}
export function isAccessor(node: Node): boolean {
if (node) {
switch (node.kind) {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return true;
}
}
return false;
return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor);
}
export function isClassLike(node: Node): boolean {
if (node) {
return node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression;
}
return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression);
}
export function isFunctionLike(node: Node): boolean {
@@ -620,7 +610,6 @@ namespace ts {
return true;
}
}
return false;
}
@@ -641,6 +630,15 @@ namespace ts {
}
}
export function getContainingClass(node: Node): ClassLikeDeclaration {
while (true) {
node = node.parent;
if (!node || isClassLike(node)) {
return <ClassLikeDeclaration>node;
}
}
}
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node {
while (true) {
node = node.parent;
@@ -653,7 +651,7 @@ namespace ts {
// then the computed property is not a 'this' container.
// A computed property name in a class needs to be a this container
// so that we can error on it.
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
if (isClassLike(node.parent.parent)) {
return node;
}
// If this is a computed property, then the parent should not
@@ -708,7 +706,7 @@ namespace ts {
// then the computed property is not a 'super' container.
// A computed property name in a class needs to be a super container
// so that we can error on it.
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
if (isClassLike(node.parent.parent)) {
return node;
}
// If this is a computed property, then the parent should not
@@ -1087,6 +1085,7 @@ namespace ts {
case SyntaxKind.ArrowFunction:
case SyntaxKind.BindingElement:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.Constructor:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.EnumMember:
@@ -1917,7 +1916,7 @@ namespace ts {
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
return node.kind === SyntaxKind.ExpressionWithTypeArguments &&
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword &&
node.parent.parent.kind === SyntaxKind.ClassDeclaration;
isClassLike(node.parent.parent);
}
// Returns false if this heritage clause element's expression contains something unsupported