diff --git a/Gulpfile.ts b/Gulpfile.ts
index bea8eb30de8..ebedfd43c23 100644
--- a/Gulpfile.ts
+++ b/Gulpfile.ts
@@ -725,16 +725,16 @@ declare module "convert-source-map" {
}
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
- const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
+ const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
return testProject.src()
.pipe(newer("built/local/bundle.js"))
.pipe(sourcemaps.init())
- .pipe(testProject)
+ .pipe(testProject())
.pipe(through2.obj((file, enc, next) => {
const originalMap = file.sourceMap;
const prebundledContent = file.contents.toString();
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
- originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
+ originalMap.sources = originalMap.sources.map(s => path.resolve(s));
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
originalMap.file = "built/local/_stream_0.js";
diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts
index 431cf460180..e5eaa46c8e5 100644
--- a/scripts/processDiagnosticMessages.ts
+++ b/scripts/processDiagnosticMessages.ts
@@ -86,7 +86,7 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap:
'/// \r\n' +
'/* @internal */\r\n' +
'namespace ts {\r\n' +
- ' export var Diagnostics = {\r\n';
+ ' export const Diagnostics = {\r\n';
var names = Utilities.getObjectKeys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts
index 7ceef2372bf..559d1b34937 100644
--- a/scripts/tslint/typeOperatorSpacingRule.ts
+++ b/scripts/tslint/typeOperatorSpacingRule.ts
@@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker {
for (let i = 1; i < types.length; i++) {
const currentType = types[i];
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
- const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
- this.addFailure(failure);
+ const sourceFile = currentType.getSourceFile();
+ const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
+ const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
+ if (previousTypeEndPos.line === currentTypeStartPos.line) {
+ const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
+ this.addFailure(failure);
+ }
}
expectedStart = currentType.end + 2;
}
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 53c0b96b31d..6fce93f7a61 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -355,11 +355,24 @@ namespace ts {
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
- forEach(symbol.declarations, declaration => {
- if (hasModifier(declaration, ModifierFlags.Default)) {
+ if (symbol.declarations && symbol.declarations.length) {
+ // If the current node is a default export of some sort, then check if
+ // there are any other default exports that we need to error on.
+ // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
+ if (isDefaultExport) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
- });
+ else {
+ // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
+ // Error on multiple export default in the following case:
+ // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
+ // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
+ if (symbol.declarations && symbol.declarations.length &&
+ (isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(node).isExportEquals))) {
+ message = Diagnostics.A_module_cannot_have_multiple_default_exports;
+ }
+ }
+ }
forEach(symbol.declarations, declaration => {
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
@@ -1114,7 +1127,7 @@ namespace ts {
}
else {
forEachChild(node, bind);
- if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) {
+ if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
bindAssignmentTargetFlow(node.operand);
}
}
@@ -1363,7 +1376,7 @@ namespace ts {
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
const body = node.kind === SyntaxKind.SourceFile ? node : (node).body;
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
- for (const stat of (body).statements) {
+ for (const stat of (body).statements) {
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
return true;
}
@@ -1948,12 +1961,15 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else {
+ // An export default clause with an expression exports a value
+ // We want to exclude both class and function here, this is necessary to issue an error when there are both
+ // default export-assignment and default export function and class declaration.
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
- declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
+ declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
}
}
@@ -2436,8 +2452,7 @@ namespace ts {
}
// If the parameter's name is 'this', then it is TypeScript syntax.
- if (subtreeFlags & TransformFlags.ContainsDecorators
- || (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) {
+ if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 9067a891796..44784c4ab23 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -121,6 +121,7 @@ namespace ts {
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
const anyType = createIntrinsicType(TypeFlags.Any, "any");
+ const autoType = createIntrinsicType(TypeFlags.Any, "any");
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
@@ -2166,7 +2167,7 @@ namespace ts {
? "any"
: (type).intrinsicName);
}
- else if (type.flags & TypeFlags.ThisType) {
+ else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
if (inObjectTypeLiteral) {
writer.reportInaccessibleThisError();
}
@@ -2184,9 +2185,14 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
- else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
+ else if (!(flags & TypeFormatFlags.InTypeAlias) && ((type.flags & TypeFlags.Anonymous && !(type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
- // Only write out inferred type with its corresponding type-alias if type-alias is visible
+ // We emit inferred type as type-alias at the current localtion if all the following is true
+ // the input type is has alias symbol that is accessible
+ // the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
+ // e.g.: export type Bar = () => [X, Y];
+ // export type Foo = Bar;
+ // export const y = (x: Foo) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
@@ -3092,6 +3098,11 @@ namespace ts {
return undefined;
}
+ function isAutoVariableInitializer(initializer: Expression) {
+ const expr = initializer && skipParentheses(initializer);
+ return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr) === undefinedSymbol;
+ }
+
function addOptionality(type: Type, optional: boolean): Type {
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
}
@@ -3130,6 +3141,14 @@ namespace ts {
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
}
+ // Use control flow type inference for non-ambient, non-exported var or let variables with no initializer
+ // or a 'null' or 'undefined' initializer.
+ if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
+ !(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) &&
+ !isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) {
+ return autoType;
+ }
+
if (declaration.kind === SyntaxKind.Parameter) {
const func = declaration.parent;
// For a parameter of a set accessor, use the type of the get accessor if one is present
@@ -3220,7 +3239,7 @@ namespace ts {
result.pattern = pattern;
}
if (hasComputedProperties) {
- result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties;
+ result.isObjectLiteralPatternWithComputedProperties = true;
}
return result;
}
@@ -3807,7 +3826,8 @@ namespace ts {
(type).instantiations[getTypeListId(type.typeParameters)] = type;
(type).target = type;
(type).typeArguments = type.typeParameters;
- type.thisType = createType(TypeFlags.TypeParameter | TypeFlags.ThisType);
+ type.thisType = createType(TypeFlags.TypeParameter);
+ type.thisType.isThisType = true;
type.thisType.symbol = symbol;
type.thisType.constraint = type;
}
@@ -3927,7 +3947,7 @@ namespace ts {
if (!links.declaredType) {
const enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
links.declaredType = enumType.flags & TypeFlags.Union ?
- enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] :
+ enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] :
enumType;
}
return links.declaredType;
@@ -5108,7 +5128,7 @@ namespace ts {
function hasConstraintReferenceTo(type: Type, target: TypeParameter): boolean {
let checked: Type[];
- while (type && !(type.flags & TypeFlags.ThisType) && type.flags & TypeFlags.TypeParameter && !contains(checked, type)) {
+ while (type && type.flags & TypeFlags.TypeParameter && !((type as TypeParameter).isThisType) && !contains(checked, type)) {
if (type === target) {
return true;
}
@@ -5471,7 +5491,8 @@ namespace ts {
type.instantiations[getTypeListId(type.typeParameters)] = type;
type.target = type;
type.typeArguments = type.typeParameters;
- type.thisType = createType(TypeFlags.TypeParameter | TypeFlags.ThisType);
+ type.thisType = createType(TypeFlags.TypeParameter);
+ type.thisType.isThisType = true;
type.thisType.constraint = type;
type.declaredProperties = properties;
type.declaredCallSignatures = emptyArray;
@@ -5584,7 +5605,26 @@ namespace ts {
return false;
}
+ function isSetOfLiteralsFromSameEnum(types: TypeSet): boolean {
+ const first = types[0];
+ if (first.flags & TypeFlags.EnumLiteral) {
+ const firstEnum = getParentOfSymbol(first.symbol);
+ for (let i = 1; i < types.length; i++) {
+ const other = types[i];
+ if (!(other.flags & TypeFlags.EnumLiteral) || (firstEnum !== getParentOfSymbol(other.symbol))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
function removeSubtypes(types: TypeSet) {
+ if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) {
+ return;
+ }
let i = types.length;
while (i > 0) {
i--;
@@ -6244,7 +6284,7 @@ namespace ts {
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
}
- function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration {
+ function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
}
@@ -6881,7 +6921,8 @@ namespace ts {
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
- if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && maybeTypeOfKind(target, TypeFlags.ObjectType)) {
+ if (maybeTypeOfKind(target, TypeFlags.ObjectType) &&
+ (!(target.flags & TypeFlags.ObjectType) || !(target as ObjectType).isObjectLiteralPatternWithComputedProperties)) {
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.name)) {
if (reportErrors) {
@@ -8667,7 +8708,9 @@ namespace ts {
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
return declaredType;
}
- const initialType = assumeInitialized ? declaredType : includeFalsyTypes(declaredType, TypeFlags.Undefined);
+ const initialType = assumeInitialized ? declaredType :
+ declaredType === autoType ? undefinedType :
+ includeFalsyTypes(declaredType, TypeFlags.Undefined);
const visitedFlowStart = visitedFlowCount;
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
visitedFlowCount = visitedFlowStart;
@@ -8741,9 +8784,12 @@ namespace ts {
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
// only need to evaluate the assigned type if the declared type is a union type.
if (isMatchingReference(reference, node)) {
- const isIncrementOrDecrement = node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression;
- return declaredType.flags & TypeFlags.Union && !isIncrementOrDecrement ?
- getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)) :
+ if (node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression) {
+ const flowType = getTypeAtFlowNode(flow.antecedent);
+ return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
+ }
+ return declaredType === autoType ? getBaseTypeOfLiteralType(getInitialOrAssignedType(node)) :
+ declaredType.flags & TypeFlags.Union ? getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)) :
declaredType;
}
// We didn't have a direct match. However, if the reference is a dotted name, this
@@ -9187,7 +9233,7 @@ namespace ts {
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
location = location.parent;
}
- if (isExpression(location) && !isAssignmentTarget(location)) {
+ if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
const type = checkExpression(location);
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
return type;
@@ -9358,13 +9404,23 @@ namespace ts {
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
// declaration container are the same).
- const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isParameter ||
- isOuterVariable || isInAmbientContext(declaration);
+ const assumeInitialized = isParameter || isOuterVariable ||
+ type !== autoType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
+ isInAmbientContext(declaration);
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
// from declaration to use, and when the variable's declared type doesn't include undefined but the
// control flow based type does include undefined.
- if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
+ if (type === autoType) {
+ if (flowType === autoType) {
+ if (compilerOptions.noImplicitAny) {
+ error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol));
+ error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(anyType));
+ }
+ return anyType;
+ }
+ }
+ else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
// Return the declared type to reduce follow-on errors
return type;
@@ -9478,7 +9534,7 @@ namespace ts {
}
function findFirstSuperCall(n: Node): Node {
- if (isSuperCallExpression(n)) {
+ if (isSuperCall(n)) {
return n;
}
else if (isFunctionLike(n)) {
@@ -9585,7 +9641,7 @@ namespace ts {
captureLexicalThis(node, container);
}
if (isFunctionLike(container) &&
- (!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
+ (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
@@ -9987,7 +10043,7 @@ namespace ts {
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
if (functionDecl.type ||
functionDecl.kind === SyntaxKind.Constructor ||
- functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
+ functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
}
@@ -10256,7 +10312,7 @@ namespace ts {
}
}
- function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression {
+ function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
}
@@ -10267,7 +10323,7 @@ namespace ts {
: undefined;
}
- function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) {
+ function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) {
return isObjectLiteralMethod(node) ?
getContextualTypeForObjectLiteralMethod(node) :
getApparentTypeOfContextualType(node);
@@ -10278,7 +10334,7 @@ namespace ts {
// If the contextual type is a union type, get the signature from each type possible and if they are
// all identical ignoring their return type, the result is same signature but with return type as
// union type of return types from these signatures
- function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature {
+ function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const type = getContextualTypeForFunctionLikeDeclaration(node);
if (!type) {
@@ -10550,7 +10606,8 @@ namespace ts {
patternWithComputedProperties = true;
}
}
- else if (contextualTypeHasPattern && !(contextualType.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties)) {
+ else if (contextualTypeHasPattern &&
+ !(contextualType.flags & TypeFlags.ObjectType && (contextualType as ObjectType).isObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.name);
@@ -10642,7 +10699,10 @@ namespace ts {
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined;
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
- result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0);
+ result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
+ if (patternWithComputedProperties) {
+ result.isObjectLiteralPatternWithComputedProperties = true;
+ }
if (inDestructuringPattern) {
result.pattern = node;
}
@@ -11214,7 +11274,7 @@ namespace ts {
return true;
}
// An instance property must be accessed through an instance of the enclosing class
- if (type.flags & TypeFlags.ThisType) {
+ if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
// get the original type -- represented as the type constraint of the 'this' type
type = getConstraintOfTypeParameter(type);
}
@@ -11264,7 +11324,7 @@ namespace ts {
const prop = getPropertyOfType(apparentType, right.text);
if (!prop) {
if (right.text && !checkAndReportErrorForExtendingInterface(node)) {
- reportNonexistentProperty(right, type.flags & TypeFlags.ThisType ? apparentType : type);
+ reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type);
}
return unknownType;
}
@@ -11664,7 +11724,7 @@ namespace ts {
argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
}
else {
- const callExpression = node;
+ const callExpression = node;
if (!callExpression.arguments) {
// This only happens when we have something of the form: 'new C'
Debug.assert(callExpression.kind === SyntaxKind.NewExpression);
@@ -11675,7 +11735,7 @@ namespace ts {
argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
// If we are missing the close paren, the call is incomplete.
- callIsIncomplete = (callExpression).arguments.end === callExpression.end;
+ callIsIncomplete = callExpression.arguments.end === callExpression.end;
typeArguments = callExpression.typeArguments;
spreadArgIndex = getSpreadArgumentIndex(args);
@@ -12762,7 +12822,7 @@ namespace ts {
* @param node The call/new expression to be checked.
* @returns On success, the expression's signature's return type. On failure, anyType.
*/
- function checkCallExpression(node: CallExpression): Type {
+ function checkCallExpression(node: CallExpression | NewExpression): Type {
// Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments);
@@ -13012,7 +13072,10 @@ namespace ts {
if (!contextualSignature) {
reportErrorsFromWidening(func, type);
}
- if (isUnitType(type) && !(contextualSignature && isLiteralContextualType(getReturnTypeOfSignature(contextualSignature)))) {
+ if (isUnitType(type) &&
+ !(contextualSignature &&
+ isLiteralContextualType(
+ contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature)))) {
type = getWidenedLiteralType(type);
}
@@ -13217,7 +13280,7 @@ namespace ts {
}
}
- if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
+ if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) {
checkCollisionWithCapturedSuperVariable(node, (node).name);
checkCollisionWithCapturedThisVariable(node, (node).name);
}
@@ -14679,7 +14742,7 @@ namespace ts {
}
function containsSuperCall(n: Node): boolean {
- if (isSuperCallExpression(n)) {
+ if (isSuperCall(n)) {
return true;
}
else if (isFunctionLike(n)) {
@@ -14735,7 +14798,7 @@ namespace ts {
let superCallStatement: ExpressionStatement;
for (const statement of statements) {
- if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) {
+ if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) {
superCallStatement = statement;
break;
}
@@ -15803,10 +15866,6 @@ namespace ts {
}
}
- function parameterIsThisKeyword(parameter: ParameterDeclaration) {
- return parameter.name && (parameter.name).originalKeywordKind === SyntaxKind.ThisKeyword;
- }
-
function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) {
return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (parameter.name).text.charCodeAt(0) === CharacterCodes._;
}
@@ -16148,6 +16207,10 @@ namespace ts {
}
}
+ function convertAutoToAny(type: Type) {
+ return type === autoType ? anyType : type;
+ }
+
// Check variable, parameter, or property declaration
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
checkDecorators(node);
@@ -16198,7 +16261,7 @@ namespace ts {
return;
}
const symbol = getSymbolOfNode(node);
- const type = getTypeOfVariableOrParameterOrProperty(symbol);
+ const type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol));
if (node === symbol.valueDeclaration) {
// Node is the primary declaration of the symbol, just validate the initializer
// Don't validate for-in initializer as it is already an error
@@ -16210,7 +16273,7 @@ namespace ts {
else {
// Node is a secondary declaration, check that type is identical to primary declaration and check that
// initializer is consistent with type associated with the node
- const declarationType = getWidenedTypeForVariableLikeDeclaration(node);
+ const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
}
@@ -16699,7 +16762,7 @@ namespace ts {
}
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
- return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
+ return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
}
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
@@ -17693,9 +17756,12 @@ namespace ts {
}
}
- checkCollisionWithCapturedThisVariable(node, node.name);
- checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
- checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+ if (isIdentifier(node.name)) {
+ checkCollisionWithCapturedThisVariable(node, node.name);
+ checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+ checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+ }
+
checkExportsOnMergedDeclarations(node);
const symbol = getSymbolOfNode(node);
@@ -18703,6 +18769,9 @@ namespace ts {
(node.parent).moduleSpecifier === node)) {
return resolveExternalModuleName(node, node);
}
+ if (isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
+ return resolveExternalModuleName(node, node);
+ }
// Fall through
case SyntaxKind.NumericLiteral:
@@ -19314,7 +19383,7 @@ namespace ts {
return undefined;
}
- function isLiteralConstDeclaration(node: VariableDeclaration): boolean {
+ function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
if (isConst(node)) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral);
@@ -19322,7 +19391,7 @@ namespace ts {
return false;
}
- function writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter) {
+ function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
writer.writeStringLiteral(literalTypeToString(type));
}
@@ -20059,7 +20128,7 @@ namespace ts {
checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
}
- function checkGrammarForOmittedArgument(node: CallExpression, args: NodeArray): boolean {
+ function checkGrammarForOmittedArgument(node: CallExpression | NewExpression, args: NodeArray): boolean {
if (args) {
const sourceFile = getSourceFileOfNode(node);
for (const arg of args) {
@@ -20070,7 +20139,7 @@ namespace ts {
}
}
- function checkGrammarArguments(node: CallExpression, args: NodeArray): boolean {
+ function checkGrammarArguments(node: CallExpression | NewExpression, args: NodeArray): boolean {
return checkGrammarForOmittedArgument(node, args);
}
@@ -20211,8 +20280,7 @@ namespace ts {
continue;
}
const name = prop.name;
- if (prop.kind === SyntaxKind.OmittedExpression ||
- name && name.kind === SyntaxKind.ComputedPropertyName) {
+ if (name && name.kind === SyntaxKind.ComputedPropertyName) {
// If the name is not a ComputedPropertyName, the grammar checking will skip it
checkGrammarComputedPropertyName(name);
}
@@ -20259,7 +20327,7 @@ namespace ts {
currentKind = SetAccessor;
}
else {
- Debug.fail("Unexpected syntax kind:" + prop.kind);
+ Debug.fail("Unexpected syntax kind:" + (prop).kind);
}
const effectiveName = getPropertyNameForPropertyNameNode(name);
@@ -20408,18 +20476,8 @@ namespace ts {
}
function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration {
- if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
- accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
- (accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
- return accessor.parameters[0];
- }
- }
-
- function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
- if (func.parameters.length &&
- func.parameters[0].name.kind === SyntaxKind.Identifier &&
- (func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
- return func.parameters[0];
+ if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2)) {
+ return getThisParameter(accessor);
}
}
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 4e1f4553642..4e03273537a 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -212,7 +212,7 @@ namespace ts {
* true for all elements, otherwise returns a new array instance containing the filtered subset.
*/
export function filter(array: T[], f: (x: T) => x is U): U[];
- export function filter(array: T[], f: (x: T) => boolean): T[]
+ export function filter(array: T[], f: (x: T) => boolean): T[];
export function filter(array: T[], f: (x: T) => boolean): T[] {
if (array) {
const len = array.length;
@@ -1813,9 +1813,9 @@ namespace ts {
export interface ObjectAllocator {
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
- getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
- getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
- getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
+ getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token;
+ getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
+ getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
@@ -1867,10 +1867,10 @@ namespace ts {
declare var process: any;
declare var require: any;
- let currentAssertionLevel: AssertionLevel;
+ export let currentAssertionLevel = AssertionLevel.None;
export function shouldAssert(level: AssertionLevel): boolean {
- return getCurrentAssertionLevel() >= level;
+ return currentAssertionLevel >= level;
}
export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void {
@@ -1887,35 +1887,6 @@ namespace ts {
export function fail(message?: string): void {
Debug.assert(/*expression*/ false, message);
}
-
- function getCurrentAssertionLevel() {
- if (currentAssertionLevel !== undefined) {
- return currentAssertionLevel;
- }
-
- if (sys === undefined) {
- return AssertionLevel.None;
- }
-
- const developmentMode = /^development$/i.test(getEnvironmentVariable("NODE_ENV"));
- currentAssertionLevel = developmentMode
- ? AssertionLevel.Normal
- : AssertionLevel.None;
-
- return currentAssertionLevel;
- }
- }
-
- export function getEnvironmentVariable(name: string, host?: CompilerHost) {
- if (host && host.getEnvironmentVariable) {
- return host.getEnvironmentVariable(name);
- }
-
- if (sys && sys.getEnvironmentVariable) {
- return sys.getEnvironmentVariable(name);
- }
-
- return "";
}
/** Remove an item from an array, moving everything to its right one space left. */
diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts
index ffc37c50830..387c35ea3ac 100644
--- a/src/compiler/declarationEmitter.ts
+++ b/src/compiler/declarationEmitter.ts
@@ -1121,7 +1121,6 @@ namespace ts {
writeLine();
}
-
function emitSpreadTypeElement(type: SpreadTypeElement) {
write("...");
emitType(type.type);
@@ -1129,7 +1128,7 @@ namespace ts {
writeLine();
}
- function emitVariableDeclaration(node: VariableDeclaration) {
+ function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
// so there is no check needed to see if declaration is visible
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
@@ -1144,7 +1143,7 @@ namespace ts {
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
// we don't want to emit property declaration with "?"
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
- (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
+ (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
@@ -1634,8 +1633,7 @@ namespace ts {
}
}
- function emitBindingElement(bindingElement: BindingElement) {
-
+ function emitBindingElement(bindingElement: BindingElement | OmittedExpression) {
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
// If bindingElement is an omittedExpression (i.e. containing elision),
// we will emit blank space (although this may differ from users' original code,
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 6004f0919a1..37a335f67cf 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -2969,6 +2969,10 @@
"category": "Error",
"code": 7033
},
+ "Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": {
+ "category": "Error",
+ "code": 7034
+ },
"You cannot rename this element.": {
"category": "Error",
"code": 8000
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index 3fba7793409..93c5ea9f435 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -655,7 +655,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.ModuleDeclaration:
return emitModuleDeclaration(node);
case SyntaxKind.ModuleBlock:
- return emitModuleBlock(node);
+ return emitModuleBlock(node);
case SyntaxKind.CaseBlock:
return emitCaseBlock(node);
case SyntaxKind.ImportEqualsDeclaration:
@@ -1394,7 +1394,7 @@ const _super = (function (geti, seti) {
}
}
- function emitBlockStatements(node: Block) {
+ function emitBlockStatements(node: BlockLike) {
if (getEmitFlags(node) & EmitFlags.SingleLine) {
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
}
@@ -1795,7 +1795,7 @@ const _super = (function (geti, seti) {
}
function emitModuleBlock(node: ModuleBlock) {
- if (isSingleLineEmptyBlock(node)) {
+ if (isEmptyBlock(node)) {
write("{ }");
}
else {
@@ -2615,7 +2615,11 @@ const _super = (function (geti, seti) {
function isSingleLineEmptyBlock(block: Block) {
return !block.multiLine
- && block.statements.length === 0
+ && isEmptyBlock(block);
+ }
+
+ function isEmptyBlock(block: BlockLike) {
+ return block.statements.length === 0
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
}
diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts
index a5e9a3429c3..f9d06370c9c 100644
--- a/src/compiler/factory.ts
+++ b/src/compiler/factory.ts
@@ -105,6 +105,7 @@ namespace ts {
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
export function createLiteral(value: string, location?: TextRange): StringLiteral;
export function createLiteral(value: number, location?: TextRange): NumericLiteral;
+ export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral;
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
if (typeof value === "number") {
@@ -120,7 +121,7 @@ namespace ts {
node.text = value;
return node;
}
- else {
+ else if (value) {
const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
node.textSourceNode = value;
node.text = value.text;
@@ -187,8 +188,8 @@ namespace ts {
// Punctuation
- export function createToken(token: SyntaxKind) {
- return createNode(token);
+ export function createToken(token: TKind) {
+ return >createNode(token);
}
// Reserved words
@@ -238,7 +239,7 @@ namespace ts {
);
}
- export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
+ export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.Parameter, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -260,7 +261,7 @@ namespace ts {
// Type members
- export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) {
+ export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.PropertyDeclaration, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -278,7 +279,7 @@ namespace ts {
return node;
}
- export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.MethodDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -381,7 +382,7 @@ namespace ts {
return node;
}
- export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: Node, name: string | BindingName, initializer?: Expression, location?: TextRange) {
+ export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.BindingElement, location);
node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName;
node.dotDotDotToken = dotDotDotToken;
@@ -497,14 +498,14 @@ namespace ts {
return node;
}
- export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) {
+ export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) {
const node = createNode(SyntaxKind.TaggedTemplateExpression, location);
node.tag = parenthesizeForAccess(tag);
node.template = template;
return node;
}
- export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) {
+ export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) {
if (node.tag !== tag || node.template !== template) {
return updateNode(createTaggedTemplate(tag, template, node), node);
}
@@ -524,7 +525,7 @@ namespace ts {
return node;
}
- export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createFunctionExpression(asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.FunctionExpression, location, flags);
node.modifiers = undefined;
node.asteriskToken = asteriskToken;
@@ -543,13 +544,13 @@ namespace ts {
return node;
}
- export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
+ export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.ArrowFunction, location, flags);
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = type;
- node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken);
+ node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken);
node.body = parenthesizeConciseBody(body);
return node;
}
@@ -613,7 +614,7 @@ namespace ts {
return node;
}
- export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) {
+ export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.PrefixUnaryExpression, location);
node.operator = operator;
node.operand = parenthesizePrefixOperand(operand);
@@ -627,7 +628,7 @@ namespace ts {
return node;
}
- export function createPostfix(operand: Expression, operator: SyntaxKind, location?: TextRange) {
+ export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) {
const node = createNode(SyntaxKind.PostfixUnaryExpression, location);
node.operand = parenthesizePostfixOperand(operand);
node.operator = operator;
@@ -641,8 +642,8 @@ namespace ts {
return node;
}
- export function createBinary(left: Expression, operator: SyntaxKind | Node, right: Expression, location?: TextRange) {
- const operatorToken = typeof operator === "number" ? createSynthesizedNode(operator) : operator;
+ export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) {
+ const operatorToken = typeof operator === "number" ? createToken(operator) : operator;
const operatorKind = operatorToken.kind;
const node = createNode(SyntaxKind.BinaryExpression, location);
node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
@@ -658,7 +659,7 @@ namespace ts {
return node;
}
- export function createConditional(condition: Expression, questionToken: Node, whenTrue: Expression, colonToken: Node, whenFalse: Expression, location?: TextRange) {
+ export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.ConditionalExpression, location);
node.condition = condition;
node.questionToken = questionToken;
@@ -675,21 +676,21 @@ namespace ts {
return node;
}
- export function createTemplateExpression(head: TemplateLiteralFragment, templateSpans: TemplateSpan[], location?: TextRange) {
+ export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) {
const node = createNode(SyntaxKind.TemplateExpression, location);
node.head = head;
node.templateSpans = createNodeArray(templateSpans);
return node;
}
- export function updateTemplateExpression(node: TemplateExpression, head: TemplateLiteralFragment, templateSpans: TemplateSpan[]) {
+ export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) {
if (node.head !== head || node.templateSpans !== templateSpans) {
return updateNode(createTemplateExpression(head, templateSpans, node), node);
}
return node;
}
- export function createYield(asteriskToken: Node, expression: Expression, location?: TextRange) {
+ export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.YieldExpression, location);
node.asteriskToken = asteriskToken;
node.expression = expression;
@@ -756,14 +757,14 @@ namespace ts {
// Misc
- export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) {
+ export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) {
const node = createNode(SyntaxKind.TemplateSpan, location);
node.expression = expression;
node.literal = literal;
return node;
}
- export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateLiteralFragment) {
+ export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) {
if (node.expression !== expression || node.literal !== literal) {
return updateNode(createTemplateSpan(expression, literal, node), node);
}
@@ -932,14 +933,14 @@ namespace ts {
return node;
}
- export function updateForOf(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
+ export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
return updateNode(createForOf(initializer, expression, statement, node), node);
}
return node;
}
- export function createContinue(label?: Identifier, location?: TextRange): BreakStatement {
+ export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement {
const node = createNode(SyntaxKind.ContinueStatement, location);
if (label) {
node.label = label;
@@ -1065,7 +1066,7 @@ namespace ts {
return node;
}
- export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.FunctionDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -1560,7 +1561,7 @@ namespace ts {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
- createSynthesizedNode(SyntaxKind.DotDotDotToken),
+ createToken(SyntaxKind.DotDotDotToken),
name,
/*questionToken*/ undefined,
/*type*/ undefined,
@@ -1735,7 +1736,7 @@ namespace ts {
export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
const generatorFunc = createFunctionExpression(
- createNode(SyntaxKind.AsteriskToken),
+ createToken(SyntaxKind.AsteriskToken),
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts
index ca702173e79..4ebdc59e6dd 100644
--- a/src/compiler/moduleNameResolver.ts
+++ b/src/compiler/moduleNameResolver.ts
@@ -95,7 +95,7 @@ namespace ts {
currentDirectory = host.getCurrentDirectory();
}
- return currentDirectory && getDefaultTypeRoots(currentDirectory, host);
+ return currentDirectory !== undefined && getDefaultTypeRoots(currentDirectory, host);
}
/**
@@ -675,23 +675,33 @@ namespace ts {
/* @internal */
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
+ return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
+ }
+
+ function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
+ return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
+ }
+
+ function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
directory = normalizeSlashes(directory);
while (true) {
const baseName = getBaseFileName(directory);
if (baseName !== "node_modules") {
- // Try to load source from the package
- const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
- if (packageResult && hasTypeScriptFileExtension(packageResult)) {
- // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
- return packageResult;
- }
- else {
- // Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
- const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
- if (typesResult || packageResult) {
- return typesResult || packageResult;
+ let packageResult: string | undefined;
+ if (!typesOnly) {
+ // Try to load source from the package
+ packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
+ if (packageResult && hasTypeScriptFileExtension(packageResult)) {
+ // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
+ return packageResult;
}
}
+
+ // Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
+ const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
+ if (typesResult || packageResult) {
+ return typesResult || packageResult;
+ }
}
const parentPath = getDirectoryPath(directory);
@@ -709,7 +719,7 @@ namespace ts {
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
const failedLookupLocations: string[] = [];
const supportedExtensions = getSupportedExtensions(compilerOptions);
- let containingDirectory = getDirectoryPath(containingFile);
+ const containingDirectory = getDirectoryPath(containingFile);
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
if (resolvedFileName) {
@@ -718,18 +728,9 @@ namespace ts {
let referencedSourceFile: string;
if (moduleHasNonRelativeName(moduleName)) {
- while (true) {
- const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
- referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
- if (referencedSourceFile) {
- break;
- }
- const parentPath = getDirectoryPath(containingDirectory);
- if (parentPath === containingDirectory) {
- break;
- }
- containingDirectory = parentPath;
- }
+ referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
+ // If we didn't find the file normally, look it up in @types.
+ loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
@@ -741,4 +742,20 @@ namespace ts {
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations };
}
+
+ /** Climb up parent directories looking for a module. */
+ function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
+ while (true) {
+ const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
+ const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
+ if (referencedSourceFile) {
+ return referencedSourceFile;
+ }
+ const parentPath = getDirectoryPath(containingDirectory);
+ if (parentPath === containingDirectory) {
+ return undefined;
+ }
+ containingDirectory = parentPath;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 348146ed3a8..ac9a9279e23 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -641,7 +641,7 @@ namespace ts {
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
- sourceFile.endOfFileToken = parseTokenNode();
+ sourceFile.endOfFileToken = parseTokenNode();
setExternalModuleIndicator(sourceFile);
@@ -1008,6 +1008,7 @@ namespace ts {
return false;
}
+ function parseOptionalToken(t: TKind): Token;
function parseOptionalToken(t: SyntaxKind): Node {
if (token() === t) {
return parseTokenNode();
@@ -1015,6 +1016,7 @@ namespace ts {
return undefined;
}
+ function parseExpectedToken(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token;
function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
return parseOptionalToken(t) ||
createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
@@ -1051,7 +1053,7 @@ namespace ts {
}
// note: this function creates only node
- function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
+ function createNode(kind: TKind, pos?: number): Node | Token | Identifier {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
@@ -1398,8 +1400,8 @@ namespace ts {
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/;
case ParsingContext.TypeArguments:
- // Tokens other than '>' are here for better error recovery
- return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken;
+ // All other tokens should cause the type-argument to terminate except comma token
+ return token() !== SyntaxKind.CommaToken;
case ParsingContext.HeritageClauses:
return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken;
case ParsingContext.JsxAttributes:
@@ -1924,7 +1926,7 @@ namespace ts {
function parseTemplateExpression(): TemplateExpression {
const template = createNode(SyntaxKind.TemplateExpression);
- template.head = parseTemplateLiteralFragment();
+ template.head = parseTemplateHead();
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
const templateSpans = createNodeArray();
@@ -1944,14 +1946,13 @@ namespace ts {
const span = createNode(SyntaxKind.TemplateSpan);
span.expression = allowInAnd(parseExpression);
- let literal: TemplateLiteralFragment;
-
+ let literal: TemplateMiddle | TemplateTail;
if (token() === SyntaxKind.CloseBraceToken) {
reScanTemplateToken();
- literal = parseTemplateLiteralFragment();
+ literal = parseTemplateMiddleOrTemplateTail();
}
else {
- literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
+ literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
}
span.literal = literal;
@@ -1962,8 +1963,16 @@ namespace ts {
return parseLiteralLikeNode(token(), internName);
}
- function parseTemplateLiteralFragment(): TemplateLiteralFragment {
- return parseLiteralLikeNode(token(), /*internName*/ false);
+ function parseTemplateHead(): TemplateHead {
+ const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
+ Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
+ return fragment;
+ }
+
+ function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail {
+ const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
+ Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind");
+ return fragment;
}
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
@@ -2738,7 +2747,7 @@ namespace ts {
}
let expr = parseAssignmentExpressionOrHigher();
- let operatorToken: Node;
+ let operatorToken: BinaryOperatorToken;
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
}
@@ -2831,7 +2840,7 @@ namespace ts {
// Note: we call reScanGreaterToken so that we get an appropriately merged token
// for cases like > > = becoming >>=
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
- return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
+ return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
}
// It wasn't an assignment or a lambda. This is a conditional expression:
@@ -3266,7 +3275,7 @@ namespace ts {
}
}
else {
- leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
}
}
@@ -3326,7 +3335,7 @@ namespace ts {
return -1;
}
- function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
+ function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression {
const node = createNode(SyntaxKind.BinaryExpression, left.pos);
node.left = left;
node.operatorToken = operatorToken;
@@ -3343,7 +3352,7 @@ namespace ts {
function parsePrefixUnaryExpression() {
const node = createNode(SyntaxKind.PrefixUnaryExpression);
- node.operator = token();
+ node.operator = token();
nextToken();
node.operand = parseSimpleUnaryExpression();
@@ -3530,7 +3539,7 @@ namespace ts {
function parseIncrementExpression(): IncrementExpression {
if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) {
const node = createNode(SyntaxKind.PrefixUnaryExpression);
- node.operator = token();
+ node.operator = token();
nextToken();
node.operand = parseLeftHandSideExpressionOrHigher();
return finishNode(node);
@@ -3546,7 +3555,7 @@ namespace ts {
if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) {
const node = createNode(SyntaxKind.PostfixUnaryExpression, expression.pos);
node.operand = expression;
- node.operator = token();
+ node.operator = token();
nextToken();
return finishNode(node);
}
@@ -3719,7 +3728,7 @@ namespace ts {
badNode.end = invalidElement.end;
badNode.left = result;
badNode.right = invalidElement;
- badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
+ badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
return badNode;
}
@@ -3855,7 +3864,7 @@ namespace ts {
if (token() === SyntaxKind.EqualsToken) {
switch (scanJsxAttributeValue()) {
case SyntaxKind.StringLiteral:
- node.initializer = parseLiteralNode();
+ node.initializer = parseLiteralNode();
break;
default:
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
@@ -3940,7 +3949,7 @@ namespace ts {
const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos);
tagExpression.tag = expression;
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
- ? parseLiteralNode()
+ ? parseLiteralNode()
: parseTemplateExpression();
expression = finishNode(tagExpression);
continue;
@@ -4984,7 +4993,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
- function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
+ function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: AsteriskToken, name: PropertyName, questionToken: QuestionToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
const method = createNode(SyntaxKind.MethodDeclaration, fullStart);
method.decorators = decorators;
method.modifiers = modifiers;
@@ -4998,7 +5007,7 @@ namespace ts {
return addJSDocComment(finishNode(method));
}
- function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: Node): ClassElement {
+ function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: QuestionToken): ClassElement {
const property = createNode(SyntaxKind.PropertyDeclaration, fullStart);
property.decorators = decorators;
property.modifiers = modifiers;
@@ -5420,7 +5429,7 @@ namespace ts {
node.flags |= flags;
node.name = parseIdentifier();
node.body = parseOptional(SyntaxKind.DotToken)
- ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
+ ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
: parseModuleBlock();
return addJSDocComment(finishNode(node));
}
@@ -5599,8 +5608,10 @@ namespace ts {
return finishNode(namespaceImport);
}
+ function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports;
+ function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports;
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
- const node = createNode(kind);
+ const node = createNode(kind);
// NamedImports:
// { }
@@ -5610,7 +5621,7 @@ namespace ts {
// ImportsList:
// ImportSpecifier
// ImportsList, ImportSpecifier
- node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
+ node.elements = | NodeArray>parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier,
SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
return finishNode(node);
@@ -5994,14 +6005,15 @@ namespace ts {
const parameter = createNode(SyntaxKind.Parameter);
parameter.type = parseJSDocType();
if (parseOptional(SyntaxKind.EqualsToken)) {
- parameter.questionToken = createNode(SyntaxKind.EqualsToken);
+ // TODO(rbuckton): Can this be changed to SyntaxKind.QuestionToken?
+ parameter.questionToken = createNode(SyntaxKind.EqualsToken);
}
return finishNode(parameter);
}
function parseJSDocTypeReference(): JSDocTypeReference {
const result = createNode(SyntaxKind.JSDocTypeReference);
- result.name = parseSimplePropertyName();
+ result.name = parseSimplePropertyName();
if (token() === SyntaxKind.LessThanToken) {
result.typeArguments = parseTypeArguments();
@@ -6329,7 +6341,7 @@ namespace ts {
function parseTag(indent: number) {
Debug.assert(token() === SyntaxKind.AtToken);
- const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
+ const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6435,7 +6447,7 @@ namespace ts {
return comments;
}
- function parseUnknownTag(atToken: Node, tagName: Identifier) {
+ function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
const result = createNode(SyntaxKind.JSDocTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
@@ -6465,7 +6477,7 @@ namespace ts {
});
}
- function parseParamTag(atToken: Node, tagName: Identifier) {
+ function parseParamTag(atToken: AtToken, tagName: Identifier) {
let typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6516,7 +6528,7 @@ namespace ts {
return finishNode(result);
}
- function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag {
+ function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
@@ -6528,7 +6540,7 @@ namespace ts {
return finishNode(result);
}
- function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag {
+ function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
@@ -6540,7 +6552,7 @@ namespace ts {
return finishNode(result);
}
- function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag {
+ function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
const name = parseJSDocIdentifierName();
@@ -6558,7 +6570,7 @@ namespace ts {
return finishNode(result);
}
- function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag {
+ function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6580,7 +6592,7 @@ namespace ts {
}
}
if (!typedefTag.jsDocTypeLiteral) {
- typedefTag.jsDocTypeLiteral = typeExpression.type;
+ typedefTag.jsDocTypeLiteral = typeExpression.type;
}
}
else {
@@ -6632,7 +6644,7 @@ namespace ts {
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
Debug.assert(token() === SyntaxKind.AtToken);
- const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
+ const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6662,7 +6674,7 @@ namespace ts {
return false;
}
- function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag {
+ function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index 91adb09c402..e300ac22fe5 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -206,7 +206,7 @@ namespace ts {
readFile: fileName => sys.readFile(fileName),
trace: (s: string) => sys.write(s + newLine),
directoryExists: directoryName => sys.directoryExists(directoryName),
- getEnvironmentVariable: name => getEnvironmentVariable(name, /*host*/ undefined),
+ getEnvironmentVariable: name => sys.getEnvironmentVariable ? sys.getEnvironmentVariable(name) : "",
getDirectories: (path: string) => sys.getDirectories(path),
realpath
};
@@ -473,6 +473,7 @@ namespace ts {
(oldOptions.configFilePath !== options.configFilePath) ||
(oldOptions.baseUrl !== options.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
+ !arrayIsEqualTo(oldOptions.lib, options.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
!equalOwnProperties(oldOptions.paths, options.paths)) {
diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts
index 1ed4b2ce826..7cf7d75bc02 100644
--- a/src/compiler/sys.ts
+++ b/src/compiler/sys.ts
@@ -83,7 +83,7 @@ namespace ts {
getEnvironmentVariable?(name: string): string;
};
- export var sys: System = (function() {
+ export let sys: System = (function() {
function getWScriptSystem(): System {
@@ -311,9 +311,18 @@ namespace ts {
return parseInt(process.version.charAt(1)) >= 4;
}
+ function isFileSystemCaseSensitive(): boolean {
+ // win32\win64 are case insensitive platforms
+ if (platform === "win32" || platform === "win64") {
+ return false;
+ }
+ // convert current file name to upper case / lower case and check if file exists
+ // (guards against cases when name is already all uppercase or lowercase)
+ return !fileExists(__filename.toUpperCase()) || !fileExists(__filename.toLowerCase());
+ }
+
const platform: string = _os.platform();
- // win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive
- const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
+ const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
function readFile(fileName: string, encoding?: string): string {
if (!fileExists(fileName)) {
@@ -628,4 +637,10 @@ namespace ts {
}
return sys;
})();
+
+ if (sys && sys.getEnvironmentVariable) {
+ Debug.currentAssertionLevel = /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"))
+ ? AssertionLevel.Normal
+ : AssertionLevel.None;
+ }
}
diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts
index 80de0615735..9f58c3ecb15 100644
--- a/src/compiler/transformers/destructuring.ts
+++ b/src/compiler/transformers/destructuring.ts
@@ -220,7 +220,7 @@ namespace ts {
function flattenDestructuring(
context: TransformationContext,
- root: BindingElement | BinaryExpression,
+ root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
value: Expression,
location: TextRange,
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
@@ -320,7 +320,7 @@ namespace ts {
}
}
- function emitBindingElement(target: BindingElement, value: Expression) {
+ function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
// Any temporary assignments needed to emit target = value should point to target
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
if (initializer) {
diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts
index 9159f65c081..bb0309e0c8e 100644
--- a/src/compiler/transformers/es6.ts
+++ b/src/compiler/transformers/es6.ts
@@ -982,7 +982,7 @@ namespace ts {
if (statementOffset < ctorStatements.length) {
firstStatement = ctorStatements[statementOffset];
- if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) {
+ if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) {
const superCall = (firstStatement as ExpressionStatement).expression as CallExpression;
superCallExpression = setOriginalNode(
saveStateAndInvoke(superCall, visitImmediateSuperCallInBody),
@@ -2308,8 +2308,7 @@ namespace ts {
extraVariableDeclarations = [];
}
// hoist collected variable declarations
- for (const name in currentState.hoistedLocalVariables) {
- const identifier = currentState.hoistedLocalVariables[name];
+ for (const identifier of currentState.hoistedLocalVariables) {
extraVariableDeclarations.push(createVariableDeclaration(identifier));
}
}
@@ -3199,7 +3198,7 @@ namespace ts {
* @param node The declaration.
* @param allowComments Allow comments for the name.
*/
- function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
+ function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts
index 6fe3187bee1..5e8a96f3ff1 100644
--- a/src/compiler/transformers/generators.ts
+++ b/src/compiler/transformers/generators.ts
@@ -528,7 +528,7 @@ namespace ts {
*
* @param node The node to visit.
*/
- function visitAccessorDeclaration(node: GetAccessorDeclaration) {
+ function visitAccessorDeclaration(node: AccessorDeclaration) {
const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
const savedInStatementContainingYield = inStatementContainingYield;
inGeneratorFunctionBody = false;
@@ -552,6 +552,7 @@ namespace ts {
const savedBlocks = blocks;
const savedBlockOffsets = blockOffsets;
const savedBlockActions = blockActions;
+ const savedBlockStack = blockStack;
const savedLabelOffsets = labelOffsets;
const savedLabelExpressions = labelExpressions;
const savedNextLabelId = nextLabelId;
@@ -566,6 +567,7 @@ namespace ts {
blocks = undefined;
blockOffsets = undefined;
blockActions = undefined;
+ blockStack = undefined;
labelOffsets = undefined;
labelExpressions = undefined;
nextLabelId = 1;
@@ -591,6 +593,7 @@ namespace ts {
blocks = savedBlocks;
blockOffsets = savedBlockOffsets;
blockActions = savedBlockActions;
+ blockStack = savedBlockStack;
labelOffsets = savedLabelOffsets;
labelExpressions = savedLabelExpressions;
nextLabelId = savedNextLabelId;
@@ -657,12 +660,12 @@ namespace ts {
}
}
- function isCompoundAssignment(kind: SyntaxKind) {
+ function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator {
return kind >= SyntaxKind.FirstCompoundAssignment
&& kind <= SyntaxKind.LastCompoundAssignment;
}
- function getOperatorForCompoundAssignment(kind: SyntaxKind) {
+ function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher {
switch (kind) {
case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken;
case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken;
diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts
index c4e9b4c31c8..516ed5433b8 100644
--- a/src/compiler/transformers/module/module.ts
+++ b/src/compiler/transformers/module/module.ts
@@ -599,7 +599,7 @@ namespace ts {
}
else {
statements.push(
- createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
+ createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
);
}
}
@@ -796,7 +796,7 @@ namespace ts {
addVarForExportedEnumOrNamespaceDeclaration(statements, original);
}
- addExportMemberAssignments(statements, original.name);
+ addExportMemberAssignments(statements, original.name);
return statements;
}
@@ -819,7 +819,7 @@ namespace ts {
}
function getDeclarationName(node: DeclarationStatement) {
- return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
+ return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
}
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
@@ -916,7 +916,7 @@ namespace ts {
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
transformedUnaryExpression = createBinary(
operand,
- createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
+ createToken(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
createLiteral(1),
/*location*/ node
);
diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts
index e64f309ae97..3c253498507 100644
--- a/src/compiler/transformers/module/system.ts
+++ b/src/compiler/transformers/module/system.ts
@@ -1201,7 +1201,7 @@ namespace ts {
* @param node The declaration statement.
*/
function getDeclarationName(node: DeclarationStatement) {
- return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
+ return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
}
function addExportStarFunction(statements: Statement[], localNames: Identifier) {
diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts
index f6e8074cb07..41f03d20f2e 100644
--- a/src/compiler/transformers/ts.ts
+++ b/src/compiler/transformers/ts.ts
@@ -989,7 +989,7 @@ namespace ts {
}
const statement = statements[index];
- if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) {
+ if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) {
result.push(visitNode(statement, visitor, isStatement));
return index + 1;
}
@@ -1801,10 +1801,41 @@ namespace ts {
case SyntaxKind.TypeReference:
return serializeTypeReferenceNode(node);
+ case SyntaxKind.IntersectionType:
+ case SyntaxKind.UnionType:
+ {
+ const unionOrIntersection = node;
+ let serializedUnion: Identifier;
+ for (const typeNode of unionOrIntersection.types) {
+ const serializedIndividual = serializeTypeNode(typeNode) as Identifier;
+ // Non identifier
+ if (serializedIndividual.kind !== SyntaxKind.Identifier) {
+ serializedUnion = undefined;
+ break;
+ }
+
+ // One of the individual is global object, return immediately
+ if (serializedIndividual.text === "Object") {
+ return serializedIndividual;
+ }
+
+ // Different types
+ if (serializedUnion && serializedUnion.text !== serializedIndividual.text) {
+ serializedUnion = undefined;
+ break;
+ }
+
+ serializedUnion = serializedIndividual;
+ }
+
+ // If we were able to find common type
+ if (serializedUnion) {
+ return serializedUnion;
+ }
+ }
+ // Fallthrough
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeLiteral:
- case SyntaxKind.UnionType:
- case SyntaxKind.IntersectionType:
case SyntaxKind.AnyKeyword:
case SyntaxKind.ThisType:
break;
@@ -2374,7 +2405,7 @@ namespace ts {
* @param node The parameter declaration node.
*/
function visitParameter(node: ParameterDeclaration) {
- if (node.name && isIdentifier(node.name) && node.name.originalKeywordKind === SyntaxKind.ThisKeyword) {
+ if (parameterIsThisKeyword(node)) {
return undefined;
}
@@ -3069,7 +3100,7 @@ namespace ts {
return createStatement(expression, /*location*/ undefined);
}
- function addExportMemberAssignment(statements: Statement[], node: DeclarationStatement) {
+ function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
const expression = createAssignment(
getExportName(node),
getLocalName(node, /*noSourceMaps*/ true)
@@ -3147,7 +3178,7 @@ namespace ts {
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
- function getLocalName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
+ function getLocalName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName);
}
@@ -3161,7 +3192,7 @@ namespace ts {
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
- function getExportName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
+ function getExportName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
if (isNamespaceExport(node)) {
return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps);
}
@@ -3177,9 +3208,9 @@ namespace ts {
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
* @param emitFlags Additional NodeEmitFlags to specify for the name.
*/
- function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
+ function getDeclarationName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name) {
- const name = getMutableClone(node.name);
+ const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 3380aead3f5..685b94f9d8e 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -439,8 +439,6 @@ namespace ts {
TypeExcludesFlags = YieldContext | AwaitContext,
}
- export type ModifiersArray = NodeArray;
-
export const enum ModifierFlags {
None = 0,
Export = 1 << 0, // Declarations
@@ -503,21 +501,34 @@ namespace ts {
hasTrailingComma?: boolean;
}
- export interface Token extends Node {
- __tokenTag: any;
+ export interface Token extends Node {
+ kind: TKind;
}
- // @kind(SyntaxKind.AbstractKeyword)
- // @kind(SyntaxKind.AsyncKeyword)
- // @kind(SyntaxKind.ConstKeyword)
- // @kind(SyntaxKind.DeclareKeyword)
- // @kind(SyntaxKind.DefaultKeyword)
- // @kind(SyntaxKind.ExportKeyword)
- // @kind(SyntaxKind.PublicKeyword)
- // @kind(SyntaxKind.PrivateKeyword)
- // @kind(SyntaxKind.ProtectedKeyword)
- // @kind(SyntaxKind.StaticKeyword)
- export interface Modifier extends Token { }
+ export type DotDotDotToken = Token;
+ export type QuestionToken = Token;
+ export type ColonToken = Token;
+ export type EqualsToken = Token;
+ export type AsteriskToken = Token;
+ export type EqualsGreaterThanToken = Token;
+ export type EndOfFileToken = Token;
+ export type AtToken = Token;
+
+ export type Modifier
+ = Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ ;
+
+ export type ModifiersArray = NodeArray;
/*@internal*/
export const enum GeneratedIdentifierKind {
@@ -528,8 +539,8 @@ namespace ts {
Node, // Unique name based on the node in the 'original' property.
}
- // @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
+ kind: SyntaxKind.Identifier;
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
@@ -541,9 +552,8 @@ namespace ts {
resolvedSymbol: Symbol;
}
- // @kind(SyntaxKind.QualifiedName)
export interface QualifiedName extends Node {
- // Must have same layout as PropertyAccess
+ kind: SyntaxKind.QualifiedName;
left: EntityName;
right: Identifier;
}
@@ -560,21 +570,21 @@ namespace ts {
}
export interface DeclarationStatement extends Declaration, Statement {
- name?: Identifier;
+ name?: Identifier | LiteralExpression;
}
- // @kind(SyntaxKind.ComputedPropertyName)
export interface ComputedPropertyName extends Node {
+ kind: SyntaxKind.ComputedPropertyName;
expression: Expression;
}
- // @kind(SyntaxKind.Decorator)
export interface Decorator extends Node {
+ kind: SyntaxKind.Decorator;
expression: LeftHandSideExpression;
}
- // @kind(SyntaxKind.TypeParameter)
export interface TypeParameterDeclaration extends Declaration {
+ kind: SyntaxKind.TypeParameter;
name: Identifier;
constraint?: TypeNode;
@@ -589,48 +599,50 @@ namespace ts {
type?: TypeNode;
}
- // @kind(SyntaxKind.CallSignature)
- export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement { }
+ export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.CallSignature;
+ }
- // @kind(SyntaxKind.ConstructSignature)
- export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { }
+ export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.ConstructSignature;
+ }
export type BindingName = Identifier | BindingPattern;
- // @kind(SyntaxKind.VariableDeclaration)
export interface VariableDeclaration extends Declaration {
+ kind: SyntaxKind.VariableDeclaration;
parent?: VariableDeclarationList;
name: BindingName; // Declared variable name
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.VariableDeclarationList)
export interface VariableDeclarationList extends Node {
+ kind: SyntaxKind.VariableDeclarationList;
declarations: NodeArray;
}
- // @kind(SyntaxKind.Parameter)
export interface ParameterDeclaration extends Declaration {
- dotDotDotToken?: Node; // Present on rest parameter
+ kind: SyntaxKind.Parameter;
+ dotDotDotToken?: DotDotDotToken; // Present on rest parameter
name: BindingName; // Declared parameter name
- questionToken?: Node; // Present on optional parameter
+ questionToken?: QuestionToken; // Present on optional parameter
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.BindingElement)
export interface BindingElement extends Declaration {
+ kind: SyntaxKind.BindingElement;
propertyName?: PropertyName; // Binding property name (in object binding pattern)
- dotDotDotToken?: Node; // Present on rest binding element
+ dotDotDotToken?: DotDotDotToken; // Present on rest binding element
name: BindingName; // Declared binding element name
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.PropertySignature)
export interface PropertySignature extends TypeElement {
+ kind: SyntaxKind.PropertySignature | SyntaxKind.JSDocRecordMember;
name: PropertyName; // Declared property name
- questionToken?: Node; // Present on optional property
+ questionToken?: QuestionToken; // Present on optional property
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
@@ -642,7 +654,8 @@ namespace ts {
// @kind(SyntaxKind.PropertyDeclaration)
export interface PropertyDeclaration extends ClassElement {
- questionToken?: Node; // Present for use with reporting a grammar error
+ kind: SyntaxKind.PropertyDeclaration;
+ questionToken?: QuestionToken; // Present for use with reporting a grammar error
name: PropertyName;
type?: TypeNode;
initializer?: Expression; // Optional initializer
@@ -651,30 +664,30 @@ namespace ts {
export interface ObjectLiteralElement extends Declaration {
_objectLiteralBrandBrand: any;
name?: PropertyName;
- }
+ }
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration | SpreadElementExpression;
- // @kind(SyntaxKind.PropertyAssignment)
export interface PropertyAssignment extends ObjectLiteralElement {
- _propertyAssignmentBrand: any;
+ kind: SyntaxKind.PropertyAssignment;
name: PropertyName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
initializer: Expression;
}
- // @kind(SyntaxKind.ShorthandPropertyAssignment)
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
+ kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
- questionToken?: Node;
+ questionToken?: QuestionToken;
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
// it is grammar error to appear in actual object initializer
- equalsToken?: Node;
+ equalsToken?: Token;
objectAssignmentInitializer?: Expression;
}
- // @kind(SyntaxKind.SpreadElementExpression)
- export interface SpreadElementExpression extends ObjectLiteralElement, SpreadExpression {
+ export interface SpreadElementExpression extends ObjectLiteralElement {
+ kind: SyntaxKind.SpreadElementExpression;
+ expression: Expression;
}
// SyntaxKind.VariableDeclaration
@@ -687,9 +700,9 @@ namespace ts {
// SyntaxKind.JSDocPropertyTag
export interface VariableLikeDeclaration extends Declaration {
propertyName?: PropertyName;
- dotDotDotToken?: Node;
+ dotDotDotToken?: DotDotDotToken;
name: DeclarationName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
type?: TypeNode;
initializer?: Expression;
}
@@ -702,15 +715,15 @@ namespace ts {
elements: NodeArray;
}
- // @kind(SyntaxKind.ObjectBindingPattern)
export interface ObjectBindingPattern extends BindingPattern {
+ kind: SyntaxKind.ObjectBindingPattern;
elements: NodeArray;
}
export type ArrayBindingElement = BindingElement | OmittedExpression;
- // @kind(SyntaxKind.ArrayBindingPattern)
export interface ArrayBindingPattern extends BindingPattern {
+ kind: SyntaxKind.ArrayBindingPattern;
elements: NodeArray;
}
@@ -725,19 +738,19 @@ namespace ts {
export interface FunctionLikeDeclaration extends SignatureDeclaration {
_functionLikeDeclarationBrand: any;
- asteriskToken?: Node;
- questionToken?: Node;
+ asteriskToken?: AsteriskToken;
+ questionToken?: QuestionToken;
body?: Block | Expression;
}
- // @kind(SyntaxKind.FunctionDeclaration)
export interface FunctionDeclaration extends FunctionLikeDeclaration, DeclarationStatement {
+ kind: SyntaxKind.FunctionDeclaration;
name?: Identifier;
body?: FunctionBody;
}
- // @kind(SyntaxKind.MethodSignature)
export interface MethodSignature extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.MethodSignature;
name: PropertyName;
}
@@ -750,126 +763,132 @@ namespace ts {
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
// of the method, or use helpers like isObjectLiteralMethodDeclaration
- // @kind(SyntaxKind.MethodDeclaration)
export interface MethodDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.MethodDeclaration;
name: PropertyName;
body?: FunctionBody;
}
- // @kind(SyntaxKind.Constructor)
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
+ kind: SyntaxKind.Constructor;
body?: FunctionBody;
}
// For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.
- // @kind(SyntaxKind.SemicolonClassElement)
export interface SemicolonClassElement extends ClassElement {
- _semicolonClassElementBrand: any;
+ kind: SyntaxKind.SemicolonClassElement;
}
- // See the comment on MethodDeclaration for the intuition behind AccessorDeclaration being a
+ // See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
// ClassElement and an ObjectLiteralElement.
- export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
- _accessorDeclarationBrand: any;
+ export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.GetAccessor;
name: PropertyName;
body: FunctionBody;
}
- // @kind(SyntaxKind.GetAccessor)
- export interface GetAccessorDeclaration extends AccessorDeclaration { }
-
- // @kind(SyntaxKind.SetAccessor)
- export interface SetAccessorDeclaration extends AccessorDeclaration { }
-
- // @kind(SyntaxKind.IndexSignature)
- export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
- _indexSignatureDeclarationBrand: any;
+ // See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
+ // ClassElement and an ObjectLiteralElement.
+ export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.SetAccessor;
+ name: PropertyName;
+ body: FunctionBody;
+ }
+
+ export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration;
+
+ export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
+ kind: SyntaxKind.IndexSignature;
}
- // @kind(SyntaxKind.AnyKeyword)
- // @kind(SyntaxKind.NumberKeyword)
- // @kind(SyntaxKind.BooleanKeyword)
- // @kind(SyntaxKind.StringKeyword)
- // @kind(SyntaxKind.SymbolKeyword)
- // @kind(SyntaxKind.VoidKeyword)
export interface TypeNode extends Node {
_typeNodeBrand: any;
}
- // @kind(SyntaxKind.ThisType)
+ export interface KeywordTypeNode extends TypeNode {
+ kind: SyntaxKind.AnyKeyword
+ | SyntaxKind.NumberKeyword
+ | SyntaxKind.BooleanKeyword
+ | SyntaxKind.StringKeyword
+ | SyntaxKind.SymbolKeyword
+ | SyntaxKind.VoidKeyword;
+ }
+
export interface ThisTypeNode extends TypeNode {
- _thisTypeNodeBrand: any;
+ kind: SyntaxKind.ThisType;
}
export interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration {
- _functionOrConstructorTypeNodeBrand: any;
+ kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType;
}
- // @kind(SyntaxKind.FunctionType)
- export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { }
+ export interface FunctionTypeNode extends FunctionOrConstructorTypeNode {
+ kind: SyntaxKind.FunctionType;
+ }
- // @kind(SyntaxKind.ConstructorType)
- export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { }
+ export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode {
+ kind: SyntaxKind.ConstructorType;
+ }
- // @kind(SyntaxKind.TypeReference)
export interface TypeReferenceNode extends TypeNode {
+ kind: SyntaxKind.TypeReference;
typeName: EntityName;
typeArguments?: NodeArray;
}
- // @kind(SyntaxKind.TypePredicate)
export interface TypePredicateNode extends TypeNode {
+ kind: SyntaxKind.TypePredicate;
parameterName: Identifier | ThisTypeNode;
type: TypeNode;
}
- // @kind(SyntaxKind.TypeQuery)
export interface TypeQueryNode extends TypeNode {
+ kind: SyntaxKind.TypeQuery;
exprName: EntityName;
}
// A TypeLiteral is the declaration node for an anonymous symbol.
- // @kind(SyntaxKind.TypeLiteral)
export interface TypeLiteralNode extends TypeNode, Declaration {
+ kind: SyntaxKind.TypeLiteral;
members: NodeArray;
}
- // @kind(SyntaxKind.ArrayType)
export interface ArrayTypeNode extends TypeNode {
+ kind: SyntaxKind.ArrayType;
elementType: TypeNode;
}
- // @kind(SyntaxKind.TupleType)
export interface TupleTypeNode extends TypeNode {
+ kind: SyntaxKind.TupleType;
elementTypes: NodeArray;
}
export interface UnionOrIntersectionTypeNode extends TypeNode {
+ kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType;
types: NodeArray;
}
- // @kind(SyntaxKind.UnionType)
- export interface UnionTypeNode extends UnionOrIntersectionTypeNode { }
+ export interface UnionTypeNode extends UnionOrIntersectionTypeNode {
+ kind: SyntaxKind.UnionType;
+ }
- // @kind(SyntaxKind.IntersectionType)
- export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { }
+ export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode {
+ kind: SyntaxKind.IntersectionType;
+ }
- // @kind(SyntaxKind.ParenthesizedType)
export interface ParenthesizedTypeNode extends TypeNode {
+ kind: SyntaxKind.ParenthesizedType;
type: TypeNode;
}
- // @kind(SyntaxKind.StringLiteralType)
export interface LiteralTypeNode extends TypeNode {
- _stringLiteralTypeBrand: any;
+ kind: SyntaxKind.LiteralType;
literal: Expression;
}
- // @kind(SyntaxKind.StringLiteral)
export interface StringLiteral extends LiteralExpression {
- _stringLiteralBrand: any;
- /* @internal */
- textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
+ kind: SyntaxKind.StringLiteral;
+ /* @internal */ textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
}
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
@@ -884,16 +903,15 @@ namespace ts {
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
}
- // @kind(SyntaxKind.OmittedExpression)
export interface OmittedExpression extends Expression {
- _omittedExpressionBrand: any;
+ kind: SyntaxKind.OmittedExpression;
}
// Represents an expression that is elided as part of a transformation to emit comments on a
// not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted.
// @internal
- // @kind(SyntaxKind.NotEmittedExpression)
export interface PartiallyEmittedExpression extends LeftHandSideExpression {
+ kind: SyntaxKind.PartiallyEmittedExpression;
expression: Expression;
}
@@ -905,16 +923,33 @@ namespace ts {
_incrementExpressionBrand: any;
}
- // @kind(SyntaxKind.PrefixUnaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-UpdateExpression
+ // see: https://tc39.github.io/ecma262/#prod-UnaryExpression
+ export type PrefixUnaryOperator
+ = SyntaxKind.PlusPlusToken
+ | SyntaxKind.MinusMinusToken
+ | SyntaxKind.PlusToken
+ | SyntaxKind.MinusToken
+ | SyntaxKind.TildeToken
+ | SyntaxKind.ExclamationToken
+ ;
+
export interface PrefixUnaryExpression extends IncrementExpression {
- operator: SyntaxKind;
+ kind: SyntaxKind.PrefixUnaryExpression;
+ operator: PrefixUnaryOperator;
operand: UnaryExpression;
}
- // @kind(SyntaxKind.PostfixUnaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-UpdateExpression
+ export type PostfixUnaryOperator
+ = SyntaxKind.PlusPlusToken
+ | SyntaxKind.MinusMinusToken
+ ;
+
export interface PostfixUnaryExpression extends IncrementExpression {
+ kind: SyntaxKind.PostfixUnaryExpression;
operand: LeftHandSideExpression;
- operator: SyntaxKind;
+ operator: PostfixUnaryOperator;
}
export interface PostfixExpression extends UnaryExpression {
@@ -929,73 +964,226 @@ namespace ts {
_memberExpressionBrand: any;
}
- // @kind(SyntaxKind.TrueKeyword)
- // @kind(SyntaxKind.FalseKeyword)
- // @kind(SyntaxKind.NullKeyword)
- // @kind(SyntaxKind.ThisKeyword)
- // @kind(SyntaxKind.SuperKeyword)
export interface PrimaryExpression extends MemberExpression {
_primaryExpressionBrand: any;
}
- // @kind(SyntaxKind.DeleteExpression)
+ export interface NullLiteral extends PrimaryExpression {
+ kind: SyntaxKind.NullKeyword;
+ }
+
+ export interface BooleanLiteral extends PrimaryExpression {
+ kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword;
+ }
+
+ export interface ThisExpression extends PrimaryExpression {
+ kind: SyntaxKind.ThisKeyword;
+ }
+
+ export interface SuperExpression extends PrimaryExpression {
+ kind: SyntaxKind.SuperKeyword;
+ }
+
export interface DeleteExpression extends UnaryExpression {
+ kind: SyntaxKind.DeleteExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.TypeOfExpression)
export interface TypeOfExpression extends UnaryExpression {
+ kind: SyntaxKind.TypeOfExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.VoidExpression)
export interface VoidExpression extends UnaryExpression {
+ kind: SyntaxKind.VoidExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.AwaitExpression)
export interface AwaitExpression extends UnaryExpression {
+ kind: SyntaxKind.AwaitExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.YieldExpression)
export interface YieldExpression extends Expression {
- asteriskToken?: Node;
+ kind: SyntaxKind.YieldExpression;
+ asteriskToken?: AsteriskToken;
expression?: Expression;
}
- // @kind(SyntaxKind.BinaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression
+ export type ExponentiationOperator
+ = SyntaxKind.AsteriskAsteriskToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-MultiplicativeOperator
+ export type MultiplicativeOperator
+ = SyntaxKind.AsteriskToken
+ | SyntaxKind.SlashToken
+ | SyntaxKind.PercentToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-MultiplicativeExpression
+ export type MultiplicativeOperatorOrHigher
+ = ExponentiationOperator
+ | MultiplicativeOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression
+ export type AdditiveOperator
+ = SyntaxKind.PlusToken
+ | SyntaxKind.MinusToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression
+ export type AdditiveOperatorOrHigher
+ = MultiplicativeOperatorOrHigher
+ | AdditiveOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-ShiftExpression
+ export type ShiftOperator
+ = SyntaxKind.LessThanLessThanToken
+ | SyntaxKind.GreaterThanGreaterThanToken
+ | SyntaxKind.GreaterThanGreaterThanGreaterThanToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-ShiftExpression
+ export type ShiftOperatorOrHigher
+ = AdditiveOperatorOrHigher
+ | ShiftOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-RelationalExpression
+ export type RelationalOperator
+ = SyntaxKind.LessThanToken
+ | SyntaxKind.LessThanEqualsToken
+ | SyntaxKind.GreaterThanToken
+ | SyntaxKind.GreaterThanEqualsToken
+ | SyntaxKind.InstanceOfKeyword
+ | SyntaxKind.InKeyword
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-RelationalExpression
+ export type RelationalOperatorOrHigher
+ = ShiftOperatorOrHigher
+ | RelationalOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-EqualityExpression
+ export type EqualityOperator
+ = SyntaxKind.EqualsEqualsToken
+ | SyntaxKind.EqualsEqualsEqualsToken
+ | SyntaxKind.ExclamationEqualsEqualsToken
+ | SyntaxKind.ExclamationEqualsToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-EqualityExpression
+ export type EqualityOperatorOrHigher
+ = RelationalOperatorOrHigher
+ | EqualityOperator;
+
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression
+ export type BitwiseOperator
+ = SyntaxKind.AmpersandToken
+ | SyntaxKind.BarToken
+ | SyntaxKind.CaretToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression
+ export type BitwiseOperatorOrHigher
+ = EqualityOperatorOrHigher
+ | BitwiseOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression
+ export type LogicalOperator
+ = SyntaxKind.AmpersandAmpersandToken
+ | SyntaxKind.BarBarToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression
+ export type LogicalOperatorOrHigher
+ = BitwiseOperatorOrHigher
+ | LogicalOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentOperator
+ export type CompoundAssignmentOperator
+ = SyntaxKind.PlusEqualsToken
+ | SyntaxKind.MinusEqualsToken
+ | SyntaxKind.AsteriskAsteriskEqualsToken
+ | SyntaxKind.AsteriskEqualsToken
+ | SyntaxKind.SlashEqualsToken
+ | SyntaxKind.PercentEqualsToken
+ | SyntaxKind.AmpersandEqualsToken
+ | SyntaxKind.BarEqualsToken
+ | SyntaxKind.CaretEqualsToken
+ | SyntaxKind.LessThanLessThanEqualsToken
+ | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken
+ | SyntaxKind.GreaterThanGreaterThanEqualsToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression
+ export type AssignmentOperator
+ = SyntaxKind.EqualsToken
+ | CompoundAssignmentOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression
+ export type AssignmentOperatorOrHigher
+ = LogicalOperatorOrHigher
+ | AssignmentOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-Expression
+ export type BinaryOperator
+ = AssignmentOperatorOrHigher
+ | SyntaxKind.CommaToken
+ ;
+
+ export type BinaryOperatorToken = Token;
+
// Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
export interface BinaryExpression extends Expression, Declaration {
+ kind: SyntaxKind.BinaryExpression;
left: Expression;
- operatorToken: Node;
+ operatorToken: BinaryOperatorToken;
right: Expression;
}
- // @kind(SyntaxKind.ConditionalExpression)
export interface ConditionalExpression extends Expression {
+ kind: SyntaxKind.ConditionalExpression;
condition: Expression;
- questionToken: Node;
+ questionToken: QuestionToken;
whenTrue: Expression;
- colonToken: Node;
+ colonToken: ColonToken;
whenFalse: Expression;
}
export type FunctionBody = Block;
export type ConciseBody = FunctionBody | Expression;
- // @kind(SyntaxKind.FunctionExpression)
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration {
+ kind: SyntaxKind.FunctionExpression;
name?: Identifier;
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
}
- // @kind(SyntaxKind.ArrowFunction)
export interface ArrowFunction extends Expression, FunctionLikeDeclaration {
- equalsGreaterThanToken: Node;
+ kind: SyntaxKind.ArrowFunction;
+ equalsGreaterThanToken: EqualsGreaterThanToken;
body: ConciseBody;
}
+ // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
+ // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters.
+ // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
export interface LiteralLikeNode extends Node {
text: string;
isUnterminated?: boolean;
@@ -1007,48 +1195,58 @@ namespace ts {
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
// or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters.
// For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
- // @kind(SyntaxKind.RegularExpressionLiteral)
- // @kind(SyntaxKind.NoSubstitutionTemplateLiteral)
export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression {
_literalExpressionBrand: any;
}
- // @kind(SyntaxKind.NumericLiteral)
+ export interface RegularExpressionLiteral extends LiteralExpression {
+ kind: SyntaxKind.RegularExpressionLiteral;
+ }
+
+ export interface NoSubstitutionTemplateLiteral extends LiteralExpression {
+ kind: SyntaxKind.NoSubstitutionTemplateLiteral;
+ }
+
export interface NumericLiteral extends LiteralExpression {
- _numericLiteralBrand: any;
+ kind: SyntaxKind.NumericLiteral;
trailingComment?: string;
}
- // @kind(SyntaxKind.TemplateHead)
- // @kind(SyntaxKind.TemplateMiddle)
- // @kind(SyntaxKind.TemplateTail)
- export interface TemplateLiteralFragment extends LiteralLikeNode {
- _templateLiteralFragmentBrand: any;
+ export interface TemplateHead extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateHead;
}
- export type Template = TemplateExpression | LiteralExpression;
+ export interface TemplateMiddle extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateMiddle;
+ }
+
+ export interface TemplateTail extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateTail;
+ }
+
+ export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral;
- // @kind(SyntaxKind.TemplateExpression)
export interface TemplateExpression extends PrimaryExpression {
- head: TemplateLiteralFragment;
+ kind: SyntaxKind.TemplateExpression;
+ head: TemplateHead;
templateSpans: NodeArray;
}
// Each of these corresponds to a substitution expression and a template literal, in that order.
// The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral.
- // @kind(SyntaxKind.TemplateSpan)
export interface TemplateSpan extends Node {
+ kind: SyntaxKind.TemplateSpan;
expression: Expression;
- literal: TemplateLiteralFragment;
+ literal: TemplateMiddle | TemplateTail;
}
- // @kind(SyntaxKind.ParenthesizedExpression)
export interface ParenthesizedExpression extends PrimaryExpression {
+ kind: SyntaxKind.ParenthesizedExpression;
expression: Expression;
}
- // @kind(SyntaxKind.ArrayLiteralExpression)
export interface ArrayLiteralExpression extends PrimaryExpression {
+ kind: SyntaxKind.ArrayLiteralExpression;
elements: NodeArray;
/* @internal */
multiLine?: boolean;
@@ -1056,6 +1254,7 @@ namespace ts {
// @kind(SyntaxKind.SpreadExpression)
export interface SpreadExpression extends Expression {
+ kind: SyntaxKind.SpreadExpression;
expression: Expression;
}
@@ -1070,8 +1269,8 @@ namespace ts {
}
// An ObjectLiteralExpression is the declaration node for an anonymous symbol.
- // @kind(SyntaxKind.ObjectLiteralExpression)
export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase {
+ kind: SyntaxKind.ObjectLiteralExpression;
/* @internal */
multiLine?: boolean;
}
@@ -1079,69 +1278,93 @@ namespace ts {
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
- // @kind(SyntaxKind.PropertyAccessExpression)
export interface PropertyAccessExpression extends MemberExpression, Declaration {
+ kind: SyntaxKind.PropertyAccessExpression;
expression: LeftHandSideExpression;
name: Identifier;
}
+
+ export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
+ expression: SuperExpression;
+ }
+
/** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */
export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression {
_propertyAccessExpressionLikeQualifiedNameBrand?: any;
expression: EntityNameExpression;
}
- // @kind(SyntaxKind.ElementAccessExpression)
export interface ElementAccessExpression extends MemberExpression {
+ kind: SyntaxKind.ElementAccessExpression;
expression: LeftHandSideExpression;
argumentExpression?: Expression;
}
- // @kind(SyntaxKind.CallExpression)
+ export interface SuperElementAccessExpression extends ElementAccessExpression {
+ expression: SuperExpression;
+ }
+
+ // see: https://tc39.github.io/ecma262/#prod-SuperProperty
+ export type SuperProperty
+ = SuperPropertyAccessExpression
+ | SuperElementAccessExpression
+ ;
+
export interface CallExpression extends LeftHandSideExpression, Declaration {
+ kind: SyntaxKind.CallExpression;
expression: LeftHandSideExpression;
typeArguments?: NodeArray;
arguments: NodeArray;
}
- // @kind(SyntaxKind.ExpressionWithTypeArguments)
+ // see: https://tc39.github.io/ecma262/#prod-SuperCall
+ export interface SuperCall extends CallExpression {
+ expression: SuperExpression;
+ }
+
export interface ExpressionWithTypeArguments extends TypeNode {
+ kind: SyntaxKind.ExpressionWithTypeArguments;
expression: LeftHandSideExpression;
typeArguments?: NodeArray;
}
- // @kind(SyntaxKind.NewExpression)
- export interface NewExpression extends CallExpression, PrimaryExpression { }
+ export interface NewExpression extends PrimaryExpression, Declaration {
+ kind: SyntaxKind.NewExpression;
+ expression: LeftHandSideExpression;
+ typeArguments?: NodeArray;
+ arguments: NodeArray;
+ }
- // @kind(SyntaxKind.TaggedTemplateExpression)
export interface TaggedTemplateExpression extends MemberExpression {
+ kind: SyntaxKind.TaggedTemplateExpression;
tag: LeftHandSideExpression;
- template: Template;
+ template: TemplateLiteral;
}
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
- // @kind(SyntaxKind.AsExpression)
export interface AsExpression extends Expression {
+ kind: SyntaxKind.AsExpression;
expression: Expression;
type: TypeNode;
}
- // @kind(SyntaxKind.TypeAssertionExpression)
export interface TypeAssertion extends UnaryExpression {
+ kind: SyntaxKind.TypeAssertionExpression;
type: TypeNode;
expression: UnaryExpression;
}
export type AssertionExpression = TypeAssertion | AsExpression;
- // @kind(SyntaxKind.NonNullExpression)
export interface NonNullExpression extends LeftHandSideExpression {
+ kind: SyntaxKind.NonNullExpression;
expression: Expression;
}
/// A JSX expression of the form ...
- // @kind(SyntaxKind.JsxElement)
export interface JsxElement extends PrimaryExpression {
+ kind: SyntaxKind.JsxElement;
openingElement: JsxOpeningElement;
children: NodeArray;
closingElement: JsxClosingElement;
@@ -1150,17 +1373,17 @@ namespace ts {
export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression;
/// The opening element of a ... JsxElement
- // @kind(SyntaxKind.JsxOpeningElement)
export interface JsxOpeningElement extends Expression {
- _openingElementBrand?: any;
+ kind: SyntaxKind.JsxOpeningElement;
tagName: JsxTagNameExpression;
attributes: NodeArray;
}
/// A JSX expression of the form
- // @kind(SyntaxKind.JsxSelfClosingElement)
- export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement {
- _selfClosingElementBrand?: any;
+ export interface JsxSelfClosingElement extends PrimaryExpression {
+ kind: SyntaxKind.JsxSelfClosingElement;
+ tagName: JsxTagNameExpression;
+ attributes: NodeArray;
}
/// Either the opening tag in a ... pair, or the lone in a self-closing form
@@ -1168,31 +1391,30 @@ namespace ts {
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
- // @kind(SyntaxKind.JsxAttribute)
export interface JsxAttribute extends Node {
+ kind: SyntaxKind.JsxAttribute;
name: Identifier;
/// JSX attribute initializers are optional; is sugar for
initializer?: StringLiteral | JsxExpression;
}
- // @kind(SyntaxKind.JsxSpreadAttribute)
export interface JsxSpreadAttribute extends Node {
+ kind: SyntaxKind.JsxSpreadAttribute;
expression: Expression;
}
- // @kind(SyntaxKind.JsxClosingElement)
export interface JsxClosingElement extends Node {
+ kind: SyntaxKind.JsxClosingElement;
tagName: JsxTagNameExpression;
}
- // @kind(SyntaxKind.JsxExpression)
export interface JsxExpression extends Expression {
+ kind: SyntaxKind.JsxExpression;
expression?: Expression;
}
- // @kind(SyntaxKind.JsxText)
export interface JsxText extends Node {
- _jsxTextExpressionBrand: any;
+ kind: SyntaxKind.JsxText;
}
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
@@ -1204,41 +1426,43 @@ namespace ts {
// Represents a statement that is elided as part of a transformation to emit comments on a
// not-emitted node.
// @internal
- // @kind(SyntaxKind.NotEmittedStatement)
export interface NotEmittedStatement extends Statement {
+ kind: SyntaxKind.NotEmittedStatement;
}
- // @kind(SyntaxKind.EmptyStatement)
- export interface EmptyStatement extends Statement { }
+ export interface EmptyStatement extends Statement {
+ kind: SyntaxKind.EmptyStatement;
+ }
- // @kind(SyntaxKind.DebuggerStatement)
- export interface DebuggerStatement extends Statement { }
+ export interface DebuggerStatement extends Statement {
+ kind: SyntaxKind.DebuggerStatement;
+ }
- // @kind(SyntaxKind.MissingDeclaration)
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
+ kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
export type BlockLike = SourceFile | Block | ModuleBlock | CaseClause;
- // @kind(SyntaxKind.Block)
export interface Block extends Statement {
+ kind: SyntaxKind.Block;
statements: NodeArray;
/*@internal*/ multiLine?: boolean;
}
- // @kind(SyntaxKind.VariableStatement)
export interface VariableStatement extends Statement {
+ kind: SyntaxKind.VariableStatement;
declarationList: VariableDeclarationList;
}
- // @kind(SyntaxKind.ExpressionStatement)
export interface ExpressionStatement extends Statement {
+ kind: SyntaxKind.ExpressionStatement;
expression: Expression;
}
- // @kind(SyntaxKind.IfStatement)
export interface IfStatement extends Statement {
+ kind: SyntaxKind.IfStatement;
expression: Expression;
thenStatement: Statement;
elseStatement?: Statement;
@@ -1248,105 +1472,105 @@ namespace ts {
statement: Statement;
}
- // @kind(SyntaxKind.DoStatement)
export interface DoStatement extends IterationStatement {
+ kind: SyntaxKind.DoStatement;
expression: Expression;
}
- // @kind(SyntaxKind.WhileStatement)
export interface WhileStatement extends IterationStatement {
+ kind: SyntaxKind.WhileStatement;
expression: Expression;
}
export type ForInitializer = VariableDeclarationList | Expression;
- // @kind(SyntaxKind.ForStatement)
export interface ForStatement extends IterationStatement {
+ kind: SyntaxKind.ForStatement;
initializer?: ForInitializer;
condition?: Expression;
incrementor?: Expression;
}
- // @kind(SyntaxKind.ForInStatement)
export interface ForInStatement extends IterationStatement {
+ kind: SyntaxKind.ForInStatement;
initializer: ForInitializer;
expression: Expression;
}
- // @kind(SyntaxKind.ForOfStatement)
export interface ForOfStatement extends IterationStatement {
+ kind: SyntaxKind.ForOfStatement;
initializer: ForInitializer;
expression: Expression;
}
- // @kind(SyntaxKind.BreakStatement)
export interface BreakStatement extends Statement {
+ kind: SyntaxKind.BreakStatement;
label?: Identifier;
}
- // @kind(SyntaxKind.ContinueStatement)
export interface ContinueStatement extends Statement {
+ kind: SyntaxKind.ContinueStatement;
label?: Identifier;
}
export type BreakOrContinueStatement = BreakStatement | ContinueStatement;
- // @kind(SyntaxKind.ReturnStatement)
export interface ReturnStatement extends Statement {
+ kind: SyntaxKind.ReturnStatement;
expression?: Expression;
}
- // @kind(SyntaxKind.WithStatement)
export interface WithStatement extends Statement {
+ kind: SyntaxKind.WithStatement;
expression: Expression;
statement: Statement;
}
- // @kind(SyntaxKind.SwitchStatement)
export interface SwitchStatement extends Statement {
+ kind: SyntaxKind.SwitchStatement;
expression: Expression;
caseBlock: CaseBlock;
possiblyExhaustive?: boolean;
}
- // @kind(SyntaxKind.CaseBlock)
export interface CaseBlock extends Node {
+ kind: SyntaxKind.CaseBlock;
clauses: NodeArray;
}
- // @kind(SyntaxKind.CaseClause)
export interface CaseClause extends Node {
+ kind: SyntaxKind.CaseClause;
expression: Expression;
statements: NodeArray;
}
- // @kind(SyntaxKind.DefaultClause)
export interface DefaultClause extends Node {
+ kind: SyntaxKind.DefaultClause;
statements: NodeArray;
}
export type CaseOrDefaultClause = CaseClause | DefaultClause;
- // @kind(SyntaxKind.LabeledStatement)
export interface LabeledStatement extends Statement {
+ kind: SyntaxKind.LabeledStatement;
label: Identifier;
statement: Statement;
}
- // @kind(SyntaxKind.ThrowStatement)
export interface ThrowStatement extends Statement {
+ kind: SyntaxKind.ThrowStatement;
expression: Expression;
}
- // @kind(SyntaxKind.TryStatement)
export interface TryStatement extends Statement {
+ kind: SyntaxKind.TryStatement;
tryBlock: Block;
catchClause?: CatchClause;
finallyBlock?: Block;
}
- // @kind(SyntaxKind.CatchClause)
export interface CatchClause extends Node {
+ kind: SyntaxKind.CatchClause;
variableDeclaration: VariableDeclaration;
block: Block;
}
@@ -1360,13 +1584,13 @@ namespace ts {
members: NodeArray;
}
- // @kind(SyntaxKind.ClassDeclaration)
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
+ kind: SyntaxKind.ClassDeclaration;
name?: Identifier;
}
- // @kind(SyntaxKind.ClassExpression)
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
+ kind: SyntaxKind.ClassExpression;
}
export interface ClassElement extends Declaration {
@@ -1377,40 +1601,40 @@ namespace ts {
export interface TypeElement extends Declaration {
_typeElementBrand: any;
name?: PropertyName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
}
- // @kind(SyntaxKind.InterfaceDeclaration)
export interface InterfaceDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.InterfaceDeclaration;
name: Identifier;
typeParameters?: NodeArray;
heritageClauses?: NodeArray;
members: NodeArray;
}
- // @kind(SyntaxKind.HeritageClause)
export interface HeritageClause extends Node {
+ kind: SyntaxKind.HeritageClause;
token: SyntaxKind;
types?: NodeArray;
}
- // @kind(SyntaxKind.TypeAliasDeclaration)
export interface TypeAliasDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.TypeAliasDeclaration;
name: Identifier;
typeParameters?: NodeArray;
type: TypeNode;
}
- // @kind(SyntaxKind.EnumMember)
export interface EnumMember extends Declaration {
+ kind: SyntaxKind.EnumMember;
// This does include ComputedPropertyName, but the parser will give an error
// if it parses a ComputedPropertyName in an EnumMember
name: PropertyName;
initializer?: Expression;
}
- // @kind(SyntaxKind.EnumDeclaration)
export interface EnumDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.EnumDeclaration;
name: Identifier;
members: NodeArray;
}
@@ -1419,21 +1643,26 @@ namespace ts {
export type ModuleName = Identifier | StringLiteral;
- // @kind(SyntaxKind.ModuleDeclaration)
export interface ModuleDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ModuleDeclaration;
name: Identifier | LiteralExpression;
- body?: ModuleBlock | ModuleDeclaration;
+ body?: ModuleBlock | NamespaceDeclaration;
+ }
+
+ export interface NamespaceDeclaration extends ModuleDeclaration {
+ name: Identifier;
+ body: ModuleBlock | NamespaceDeclaration;
}
- // @kind(SyntaxKind.ModuleBlock)
export interface ModuleBlock extends Node, Statement {
+ kind: SyntaxKind.ModuleBlock;
statements: NodeArray;
}
export type ModuleReference = EntityName | ExternalModuleReference;
- // @kind(SyntaxKind.ImportEqualsDeclaration)
export interface ImportEqualsDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ImportEqualsDeclaration;
name: Identifier;
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
@@ -1441,8 +1670,8 @@ namespace ts {
moduleReference: ModuleReference;
}
- // @kind(SyntaxKind.ExternalModuleReference)
export interface ExternalModuleReference extends Node {
+ kind: SyntaxKind.ExternalModuleReference;
expression?: Expression;
}
@@ -1450,8 +1679,8 @@ namespace ts {
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
// In rest of the cases, module specifier is string literal corresponding to module
// ImportClause information is shown at its declaration below.
- // @kind(SyntaxKind.ImportDeclaration)
export interface ImportDeclaration extends Statement {
+ kind: SyntaxKind.ImportDeclaration;
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@@ -1464,57 +1693,57 @@ namespace ts {
// import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns }
// import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
- // @kind(SyntaxKind.ImportClause)
export interface ImportClause extends Declaration {
+ kind: SyntaxKind.ImportClause;
name?: Identifier; // Default binding
namedBindings?: NamedImportBindings;
}
- // @kind(SyntaxKind.NamespaceImport)
export interface NamespaceImport extends Declaration {
+ kind: SyntaxKind.NamespaceImport;
name: Identifier;
}
- // @kind(SyntaxKind.NamespaceExportDeclaration)
export interface NamespaceExportDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.NamespaceExportDeclaration;
name: Identifier;
moduleReference: LiteralLikeNode;
}
- // @kind(SyntaxKind.ExportDeclaration)
export interface ExportDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ExportDeclaration;
exportClause?: NamedExports;
moduleSpecifier?: Expression;
}
- // @kind(SyntaxKind.NamedImports)
export interface NamedImports extends Node {
+ kind: SyntaxKind.NamedImports;
elements: NodeArray;
}
- // @kind(SyntaxKind.NamedExports)
export interface NamedExports extends Node {
+ kind: SyntaxKind.NamedExports;
elements: NodeArray;
}
export type NamedImportsOrExports = NamedImports | NamedExports;
- // @kind(SyntaxKind.ImportSpecifier)
export interface ImportSpecifier extends Declaration {
+ kind: SyntaxKind.ImportSpecifier;
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
- // @kind(SyntaxKind.ExportSpecifier)
export interface ExportSpecifier extends Declaration {
+ kind: SyntaxKind.ExportSpecifier;
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier;
- // @kind(SyntaxKind.ExportAssignment)
export interface ExportAssignment extends DeclarationStatement {
+ kind: SyntaxKind.ExportAssignment;
isExportEquals?: boolean;
expression: Expression;
}
@@ -1529,8 +1758,8 @@ namespace ts {
}
// represents a top level: { type } expression in a JSDoc comment.
- // @kind(SyntaxKind.JSDocTypeExpression)
export interface JSDocTypeExpression extends Node {
+ kind: SyntaxKind.JSDocTypeExpression;
type: JSDocType;
}
@@ -1538,139 +1767,141 @@ namespace ts {
_jsDocTypeBrand: any;
}
- // @kind(SyntaxKind.JSDocAllType)
export interface JSDocAllType extends JSDocType {
- _JSDocAllTypeBrand: any;
+ kind: SyntaxKind.JSDocAllType;
}
- // @kind(SyntaxKind.JSDocUnknownType)
export interface JSDocUnknownType extends JSDocType {
- _JSDocUnknownTypeBrand: any;
+ kind: SyntaxKind.JSDocUnknownType;
}
- // @kind(SyntaxKind.JSDocArrayType)
export interface JSDocArrayType extends JSDocType {
+ kind: SyntaxKind.JSDocArrayType;
elementType: JSDocType;
}
- // @kind(SyntaxKind.JSDocUnionType)
export interface JSDocUnionType extends JSDocType {
+ kind: SyntaxKind.JSDocUnionType;
types: NodeArray;
}
- // @kind(SyntaxKind.JSDocTupleType)
export interface JSDocTupleType extends JSDocType {
+ kind: SyntaxKind.JSDocTupleType;
types: NodeArray;
}
- // @kind(SyntaxKind.JSDocNonNullableType)
export interface JSDocNonNullableType extends JSDocType {
+ kind: SyntaxKind.JSDocNonNullableType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocNullableType)
export interface JSDocNullableType extends JSDocType {
+ kind: SyntaxKind.JSDocNullableType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocRecordType)
- export interface JSDocRecordType extends JSDocType, TypeLiteralNode {
- literal: TypeLiteralNode;
+ export interface JSDocRecordType extends JSDocType {
+ kind: SyntaxKind.JSDocRecordType;
+ literal: TypeLiteralNode;
}
- // @kind(SyntaxKind.JSDocTypeReference)
export interface JSDocTypeReference extends JSDocType {
+ kind: SyntaxKind.JSDocTypeReference;
name: EntityName;
typeArguments: NodeArray;
}
- // @kind(SyntaxKind.JSDocOptionalType)
export interface JSDocOptionalType extends JSDocType {
+ kind: SyntaxKind.JSDocOptionalType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocFunctionType)
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
+ kind: SyntaxKind.JSDocFunctionType;
parameters: NodeArray;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocVariadicType)
export interface JSDocVariadicType extends JSDocType {
+ kind: SyntaxKind.JSDocVariadicType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocConstructorType)
export interface JSDocConstructorType extends JSDocType {
+ kind: SyntaxKind.JSDocConstructorType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocThisType)
export interface JSDocThisType extends JSDocType {
+ kind: SyntaxKind.JSDocThisType;
type: JSDocType;
}
export interface JSDocLiteralType extends JSDocType {
+ kind: SyntaxKind.JSDocLiteralType;
literal: LiteralTypeNode;
}
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
- // @kind(SyntaxKind.JSDocRecordMember)
export interface JSDocRecordMember extends PropertySignature {
+ kind: SyntaxKind.JSDocRecordMember;
name: Identifier | LiteralExpression;
type?: JSDocType;
}
- // @kind(SyntaxKind.JSDocComment)
export interface JSDoc extends Node {
+ kind: SyntaxKind.JSDocComment;
tags: NodeArray | undefined;
comment: string | undefined;
}
- // @kind(SyntaxKind.JSDocTag)
export interface JSDocTag extends Node {
- atToken: Node;
+ atToken: AtToken;
tagName: Identifier;
comment: string | undefined;
}
- // @kind(SyntaxKind.JSDocTemplateTag)
+ export interface JSDocUnknownTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTag;
+ }
+
export interface JSDocTemplateTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTemplateTag;
typeParameters: NodeArray;
}
- // @kind(SyntaxKind.JSDocReturnTag)
export interface JSDocReturnTag extends JSDocTag {
+ kind: SyntaxKind.JSDocReturnTag;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypeTag)
export interface JSDocTypeTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTypeTag;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypedefTag)
export interface JSDocTypedefTag extends JSDocTag, Declaration {
+ kind: SyntaxKind.JSDocTypedefTag;
name?: Identifier;
typeExpression?: JSDocTypeExpression;
jsDocTypeLiteral?: JSDocTypeLiteral;
}
- // @kind(SyntaxKind.JSDocPropertyTag)
export interface JSDocPropertyTag extends JSDocTag, TypeElement {
+ kind: SyntaxKind.JSDocPropertyTag;
name: Identifier;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypeLiteral)
export interface JSDocTypeLiteral extends JSDocType {
+ kind: SyntaxKind.JSDocTypeLiteral;
jsDocPropertyTags?: NodeArray;
jsDocTypeTag?: JSDocTypeTag;
}
- // @kind(SyntaxKind.JSDocParameterTag)
export interface JSDocParameterTag extends JSDocTag {
+ kind: SyntaxKind.JSDocParameterTag;
/** the parameter name, if provided *before* the type (TypeScript-style) */
preParameterName?: Identifier;
typeExpression?: JSDocTypeExpression;
@@ -1750,10 +1981,10 @@ namespace ts {
}
// Source files are declarations when they are external modules.
- // @kind(SyntaxKind.SourceFile)
export interface SourceFile extends Declaration {
+ kind: SyntaxKind.SourceFile;
statements: NodeArray;
- endOfFileToken: Node;
+ endOfFileToken: Token;
fileName: string;
/* internal */ path: Path;
@@ -2097,13 +2328,12 @@ namespace ts {
type: Type;
}
- // @kind (TypePredicateKind.This)
export interface ThisTypePredicate extends TypePredicateBase {
- _thisTypePredicateBrand: any;
+ kind: TypePredicateKind.This;
}
- // @kind (TypePredicateKind.Identifier)
export interface IdentifierTypePredicate extends TypePredicateBase {
+ kind: TypePredicateKind.Identifier;
parameterName: string;
parameterIndex: number;
}
@@ -2178,8 +2408,8 @@ namespace ts {
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile;
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[];
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
- isLiteralConstDeclaration(node: VariableDeclaration): boolean;
- writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter): void;
+ isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
+ writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void;
}
export const enum SymbolFlags {
@@ -2404,10 +2634,7 @@ namespace ts {
ContainsObjectLiteral = 1 << 26, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 27, // Type is or contains object literal type
- ThisType = 1 << 28, // This type
- ObjectLiteralPatternWithComputedProperties = 1 << 29, // Object literal type implied by binding pattern has computed properties
- Spread = 1 << 30, // Spread types
- // TODO: Move some types out to make room for Spread.
+ Spread = 1 << 28, // Spread types
/* @internal */
Nullable = Undefined | Null,
@@ -2476,7 +2703,9 @@ namespace ts {
}
// Object types (TypeFlags.ObjectType)
- export interface ObjectType extends Type { }
+ export interface ObjectType extends Type {
+ isObjectLiteralPatternWithComputedProperties?: boolean;
+ }
// Class and interface types (TypeFlags.Class and TypeFlags.Interface)
export interface InterfaceType extends ObjectType {
@@ -2581,6 +2810,8 @@ namespace ts {
mapper?: TypeMapper; // Instantiation mapper
/* @internal */
resolvedApparentType: Type;
+ /* @internal */
+ isThisType?: boolean;
}
export const enum SignatureKind {
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 010d221d430..f9bf2e436a6 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -609,7 +609,7 @@ namespace ts {
return !!(getCombinedNodeFlags(node) & NodeFlags.Let);
}
- export function isSuperCallExpression(n: Node): boolean {
+ export function isSuperCall(n: Node): n is SuperCall {
return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword;
}
@@ -1047,7 +1047,7 @@ namespace ts {
/**
* Determines whether a node is a property or element access expression for super.
*/
- export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
+ export function isSuperProperty(node: Node): node is SuperProperty {
const kind = node.kind;
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
&& (node).expression.kind === SyntaxKind.SuperKeyword;
@@ -1375,7 +1375,7 @@ namespace ts {
}
}
- export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
+ export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
return node;
}
@@ -2459,7 +2459,7 @@ namespace ts {
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
}
- export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string {
+ export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): string {
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
if (!file || isDeclarationFile(file)) {
return undefined;
@@ -2707,15 +2707,35 @@ namespace ts {
});
}
- export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
+ /** Get the type annotaion for the value parameter. */
+ export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
if (accessor && accessor.parameters.length > 0) {
- const hasThis = accessor.parameters.length === 2 &&
- accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
- (accessor.parameters[0].name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword;
+ const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
return accessor.parameters[hasThis ? 1 : 0].type;
}
}
+ export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
+ if (signature.parameters.length) {
+ const thisParameter = signature.parameters[0];
+ if (parameterIsThisKeyword(thisParameter)) {
+ return thisParameter;
+ }
+ }
+ }
+
+ export function parameterIsThisKeyword(parameter: ParameterDeclaration): boolean {
+ return isThisIdentifier(parameter.name);
+ }
+
+ export function isThisIdentifier(node: Node | undefined): boolean {
+ return node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
+ }
+
+ export function identifierIsThisKeyword(id: Identifier): boolean {
+ return id.originalKeywordKind === SyntaxKind.ThisKeyword;
+ }
+
export interface AllAccessorDeclarations {
firstAccessor: AccessorDeclaration;
secondAccessor: AccessorDeclaration;
@@ -3605,14 +3625,14 @@ namespace ts {
return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken;
}
- function isTemplateLiteralFragmentKind(kind: SyntaxKind) {
- return kind === SyntaxKind.TemplateHead
- || kind === SyntaxKind.TemplateMiddle
- || kind === SyntaxKind.TemplateTail;
+ export function isTemplateHead(node: Node): node is TemplateHead {
+ return node.kind === SyntaxKind.TemplateHead;
}
- export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment {
- return isTemplateLiteralFragmentKind(node.kind);
+ export function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail {
+ const kind = node.kind;
+ return kind === SyntaxKind.TemplateMiddle
+ || kind === SyntaxKind.TemplateTail;
}
// Identifiers
@@ -3778,7 +3798,7 @@ namespace ts {
return node.kind === SyntaxKind.CallExpression;
}
- export function isTemplate(node: Node): node is Template {
+ export function isTemplateLiteral(node: Node): node is TemplateLiteral {
const kind = node.kind;
return kind === SyntaxKind.TemplateExpression
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts
index c3d2dbce255..4462578fd05 100644
--- a/src/compiler/visitor.ts
+++ b/src/compiler/visitor.ts
@@ -799,7 +799,7 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
return updateTaggedTemplate(node,
visitNode((node).tag, visitor, isExpression),
- visitNode((node).template, visitor, isTemplate));
+ visitNode((node).template, visitor, isTemplateLiteral));
case SyntaxKind.ParenthesizedExpression:
return updateParen(node,
@@ -862,7 +862,7 @@ namespace ts {
case SyntaxKind.TemplateExpression:
return updateTemplateExpression(node,
- visitNode((node).head, visitor, isTemplateLiteralFragment),
+ visitNode((node).head, visitor, isTemplateHead),
visitNodes((node).templateSpans, visitor, isTemplateSpan));
case SyntaxKind.YieldExpression:
@@ -890,7 +890,7 @@ namespace ts {
case SyntaxKind.TemplateSpan:
return updateTemplateSpan(node,
visitNode((node).expression, visitor, isExpression),
- visitNode((node).literal, visitor, isTemplateLiteralFragment));
+ visitNode((node).literal, visitor, isTemplateMiddleOrTemplateTail));
// Element
case SyntaxKind.Block:
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index 0b4418b1236..49f834963ee 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -754,6 +754,13 @@ namespace FourSlash {
}
}
+ public verifyCompletionListIsGlobal(expected: boolean) {
+ const completions = this.getCompletionListAtCaret();
+ if (completions && completions.isGlobalCompletion !== expected) {
+ this.raiseError(`verifyCompletionListIsGlobal failed - expected result to be ${completions.isGlobalCompletion}`);
+ }
+ }
+
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
const completions = this.getCompletionListAtCaret();
if (completions) {
@@ -3046,6 +3053,10 @@ namespace FourSlashInterface {
this.state.verifyCompletionListIsEmpty(this.negative);
}
+ public completionListIsGlobal(expected: boolean) {
+ this.state.verifyCompletionListIsGlobal(expected);
+ }
+
public completionListAllowsNewIdentifier() {
this.state.verifyCompletionListAllowsNewIdentifier(this.negative);
}
diff --git a/src/harness/harness.ts b/src/harness/harness.ts
index 522bfd4bcdd..116147e8e68 100644
--- a/src/harness/harness.ts
+++ b/src/harness/harness.ts
@@ -509,7 +509,7 @@ namespace Harness {
tryEnableSourceMapsForHost?(): void;
getEnvironmentVariable?(name: string): string;
}
- export var IO: IO;
+ export let IO: IO;
// harness always uses one kind of new line
const harnessNewLine = "\r\n";
@@ -925,7 +925,7 @@ namespace Harness {
export const defaultLibFileName = "lib.d.ts";
export const es2015DefaultLibFileName = "lib.es2015.d.ts";
- const libFileNameSourceFileMap= ts.createMap({
+ const libFileNameSourceFileMap = ts.createMap({
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
});
diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts
index 5b934cc4b0b..9f0d6ae6a17 100644
--- a/src/harness/unittests/tsserverProjectSystem.ts
+++ b/src/harness/unittests/tsserverProjectSystem.ts
@@ -1898,6 +1898,64 @@ namespace ts.projectSystem {
projectService.closeExternalProject(projectName);
projectService.checkNumberOfProjects({});
});
+
+ it("correctly handles changes in lib section of config file", () => {
+ const libES5 = {
+ path: "/compiler/lib.es5.d.ts",
+ content: "declare const eval: any"
+ };
+ const libES2015Promise = {
+ path: "/compiler/lib.es2015.promise.d.ts",
+ content: "declare class Promise {}"
+ };
+ const app = {
+ path: "/src/app.ts",
+ content: "var x: Promise;"
+ };
+ const config1 = {
+ path: "/src/tsconfig.json",
+ content: JSON.stringify(
+ {
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "noImplicitAny": true,
+ "sourceMap": false,
+ "lib": [
+ "es5"
+ ]
+ }
+ })
+ };
+ const config2 = {
+ path: config1.path,
+ content: JSON.stringify(
+ {
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "noImplicitAny": true,
+ "sourceMap": false,
+ "lib": [
+ "es5",
+ "es2015.promise"
+ ]
+ }
+ })
+ };
+ const host = createServerHost([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" });
+ const projectService = createProjectService(host);
+ projectService.openClientFile(app.path);
+
+ projectService.checkNumberOfProjects({ configuredProjects: 1 });
+ checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path]);
+
+ host.reloadFS([libES5, libES2015Promise, app, config2]);
+ host.triggerFileWatcherCallback(config1.path);
+
+ projectService.checkNumberOfProjects({ configuredProjects: 1 });
+ checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]);
+ });
});
describe("prefer typings to js", () => {
diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts
index ce719668acf..ccff01a8722 100644
--- a/src/lib/es5.d.ts
+++ b/src/lib/es5.d.ts
@@ -1200,6 +1200,30 @@ interface Array {
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
+ /**
+ * Calls a defined callback function on each element of an array, and returns an array that contains the results.
+ * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
+ * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
+ */
+ map(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U];
+ /**
+ * Calls a defined callback function on each element of an array, and returns an array that contains the results.
+ * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
+ * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
+ */
+ map(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U];
+ /**
+ * Calls a defined callback function on each element of an array, and returns an array that contains the results.
+ * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
+ * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
+ */
+ map(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U];
+ /**
+ * Calls a defined callback function on each element of an array, and returns an array that contains the results.
+ * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
+ * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
+ */
+ map(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U];
/**
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
diff --git a/src/server/client.ts b/src/server/client.ts
index 5032056c2f3..688408dfb88 100644
--- a/src/server/client.ts
+++ b/src/server/client.ts
@@ -214,6 +214,7 @@ namespace ts.server {
const response = this.processResponse(request);
return {
+ isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: false,
entries: response.body.map(entry => {
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 2b28e66bf88..51310c90a6b 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -12,7 +12,7 @@ namespace ts.server {
export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
export type ProjectServiceEvent =
- { eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile?: string, configFileName: string, diagnostics: Diagnostic[] } }
+ { eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile?: string, configFileName: string, diagnostics: Diagnostic[] } };
export interface ProjectServiceEventHandler {
(event: ProjectServiceEvent): void;
diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts
index f0dfe4eb130..bad403deaf9 100644
--- a/src/server/protocol.d.ts
+++ b/src/server/protocol.d.ts
@@ -606,6 +606,12 @@ declare namespace ts.server.protocol {
/** Defines space handling after opening and before closing non empty brackets. Default value is false. */
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
+ /** Defines space handling before and after template string braces. Default value is false. */
+ insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
+
+ /** Defines space handling before and after JSX expression braces. Default value is false. */
+ insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
+
/** Defines whether an open brace is put onto a new line for functions or not. Default value is false. */
placeOpenBraceOnNewLineForFunctions?: boolean;
diff --git a/src/server/server.ts b/src/server/server.ts
index 23e6b7f0de9..d59100bb57c 100644
--- a/src/server/server.ts
+++ b/src/server/server.ts
@@ -523,6 +523,8 @@ namespace ts.server {
process.on("uncaughtException", function (err: Error) {
ioSession.logError(err, "unknown");
});
+ // See https://github.com/Microsoft/TypeScript/issues/11348
+ (process as any).noAsar = true;
// Start listening
ioSession.listen();
}
\ No newline at end of file
diff --git a/src/server/session.ts b/src/server/session.ts
index d076d5deb6d..edb79e3a0ef 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -1109,7 +1109,7 @@ namespace ts.server {
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
const { file, project } = this.getFileAndProject(args);
- const items = project.getLanguageService().getNavigationBarItems(file);
+ const items = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(file);
if (!items) {
return undefined;
}
diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json
index 9e65eb2b8bc..7eb8c28f383 100644
--- a/src/server/tsconfig.json
+++ b/src/server/tsconfig.json
@@ -18,7 +18,7 @@
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
- "lshost.ts",
+ "lsHost.ts",
"typingsCache.ts",
"project.ts",
"editorServices.ts",
diff --git a/src/services/classifier.ts b/src/services/classifier.ts
index 29a878224cd..c22aec6a786 100644
--- a/src/services/classifier.ts
+++ b/src/services/classifier.ts
@@ -954,8 +954,7 @@ namespace ts {
return;
case SyntaxKind.Parameter:
if ((token.parent).name === token) {
- const isThis = token.kind === SyntaxKind.Identifier && (token).originalKeywordKind === SyntaxKind.ThisKeyword;
- return isThis ? ClassificationType.keyword : ClassificationType.parameterName;
+ return isThisIdentifier(token) ? ClassificationType.keyword : ClassificationType.parameterName;
}
return;
}
diff --git a/src/services/completions.ts b/src/services/completions.ts
index a43717921c4..3fff0df5f9e 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -14,17 +14,17 @@ namespace ts.Completions {
return undefined;
}
- const { symbols, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
+ const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
if (isJsDocTagName) {
// If the current position is a jsDoc tag name, only tag names should be provided for completion
- return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
+ return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
}
const entries: CompletionEntry[] = [];
if (isSourceFileJavaScript(sourceFile)) {
- const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ false);
+ const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true);
addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames));
}
else {
@@ -56,7 +56,7 @@ namespace ts.Completions {
addRange(entries, keywordCompletions);
}
- return { isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries };
+ return { isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries };
function getJavaScriptCompletionEntries(sourceFile: SourceFile, position: number, uniqueNames: Map): CompletionEntry[] {
const entries: CompletionEntry[] = [];
@@ -138,7 +138,9 @@ namespace ts.Completions {
return undefined;
}
- if (node.parent.kind === SyntaxKind.PropertyAssignment && node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression) {
+ if (node.parent.kind === SyntaxKind.PropertyAssignment &&
+ node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression &&
+ (node.parent).name === node) {
// Get quoted name of properties of the object literal expression
// i.e. interface ConfigFiles {
// 'jspm:dev': string
@@ -190,7 +192,7 @@ namespace ts.Completions {
if (type) {
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/false);
if (entries.length) {
- return { isMemberCompletion: true, isNewIdentifierLocation: true, entries };
+ return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
}
}
}
@@ -209,7 +211,7 @@ namespace ts.Completions {
}
if (entries.length) {
- return { isMemberCompletion: false, isNewIdentifierLocation: true, entries };
+ return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries };
}
return undefined;
@@ -221,7 +223,7 @@ namespace ts.Completions {
if (type) {
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/false);
if (entries.length) {
- return { isMemberCompletion: true, isNewIdentifierLocation: true, entries };
+ return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
}
}
return undefined;
@@ -233,7 +235,7 @@ namespace ts.Completions {
const entries: CompletionEntry[] = [];
addStringLiteralCompletionsFromType(type, entries);
if (entries.length) {
- return { isMemberCompletion: false, isNewIdentifierLocation: false, entries };
+ return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
}
}
return undefined;
@@ -281,6 +283,7 @@ namespace ts.Completions {
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span);
}
return {
+ isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: true,
entries
@@ -558,6 +561,7 @@ namespace ts.Completions {
}
return {
+ isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: true,
entries
@@ -812,7 +816,7 @@ namespace ts.Completions {
}
if (isJsDocTagName) {
- return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
+ return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
}
if (!insideJsDocTagExpression) {
@@ -884,6 +888,7 @@ namespace ts.Completions {
}
const semanticStart = timestamp();
+ let isGlobalCompletion = false;
let isMemberCompletion: boolean;
let isNewIdentifierLocation: boolean;
let symbols: Symbol[] = [];
@@ -919,14 +924,16 @@ namespace ts.Completions {
if (!tryGetGlobalSymbols()) {
return undefined;
}
+ isGlobalCompletion = true;
}
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
- return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
+ return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
function getTypeScriptMemberSymbols(): void {
// Right of dot member completion list
+ isGlobalCompletion = false;
isMemberCompletion = true;
isNewIdentifierLocation = false;
@@ -996,6 +1003,7 @@ namespace ts.Completions {
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
// Cursor is inside a JSX self-closing element or opening element
attrsType = typeChecker.getJsxElementAttributesType(jsxContainer);
+ isGlobalCompletion = false;
if (attrsType) {
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes);
diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts
index b998d57a265..16108450d2c 100644
--- a/src/services/formatting/formatting.ts
+++ b/src/services/formatting/formatting.ts
@@ -175,7 +175,7 @@ namespace ts.formatting {
return rangeContainsRange((parent).members, node);
case SyntaxKind.ModuleDeclaration:
const body = (parent).body;
- return body && body.kind === SyntaxKind.Block && rangeContainsRange((body).statements, node);
+ return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((body).statements, node);
case SyntaxKind.SourceFile:
case SyntaxKind.Block:
case SyntaxKind.ModuleBlock:
diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts
index 4fffa394fc5..84f83a9c7db 100644
--- a/src/services/formatting/smartIndenter.ts
+++ b/src/services/formatting/smartIndenter.ts
@@ -332,7 +332,7 @@ namespace ts.formatting {
(node.parent).expression !== node) {
const fullCallOrNewExpression = (node.parent).expression;
- const startingExpression = getStartingExpression(