mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into jsdoc-values-as-namespaces
This commit is contained in:
@@ -517,16 +517,15 @@ namespace ts {
|
||||
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
|
||||
// A non-async IIFE is considered part of the containing control flow. Return statements behave
|
||||
// similarly to break statements that exit to a label just past the statement body.
|
||||
if (isIIFE) {
|
||||
currentReturnTarget = createBranchLabel();
|
||||
}
|
||||
else {
|
||||
if (!isIIFE) {
|
||||
currentFlow = { flags: FlowFlags.Start };
|
||||
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
|
||||
(<FlowStart>currentFlow).container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
|
||||
}
|
||||
currentReturnTarget = undefined;
|
||||
}
|
||||
// We create a return control flow graph for IIFEs and constructors. For constructors
|
||||
// we use the return control flow graph in strict property intialization checks.
|
||||
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
|
||||
currentBreakTarget = undefined;
|
||||
currentContinueTarget = undefined;
|
||||
activeLabels = undefined;
|
||||
@@ -541,11 +540,14 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
node.flags |= emitFlags;
|
||||
}
|
||||
if (isIIFE) {
|
||||
if (currentReturnTarget) {
|
||||
addAntecedent(currentReturnTarget, currentFlow);
|
||||
currentFlow = finishFlowLabel(currentReturnTarget);
|
||||
if (node.kind === SyntaxKind.Constructor) {
|
||||
(<ConstructorDeclaration>node).returnFlowNode = currentFlow;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!isIIFE) {
|
||||
currentFlow = saveCurrentFlow;
|
||||
}
|
||||
currentBreakTarget = saveBreakTarget;
|
||||
|
||||
+101
-47
@@ -69,6 +69,7 @@ namespace ts {
|
||||
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
|
||||
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
|
||||
const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
|
||||
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
|
||||
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
|
||||
|
||||
@@ -8879,6 +8880,7 @@ namespace ts {
|
||||
// An object type S is considered to be derived from an object type T if
|
||||
// S is a union type and every constituent of S is derived from T,
|
||||
// T is a union type and S is derived from at least one constituent of T, or
|
||||
// S is a type variable with a base constraint that is derived from T,
|
||||
// T is one of the global types Object and Function and S is a subtype of T, or
|
||||
// T occurs directly or indirectly in an 'extends' clause of S.
|
||||
// Note that this check ignores type parameters and only considers the
|
||||
@@ -8886,6 +8888,7 @@ namespace ts {
|
||||
function isTypeDerivedFrom(source: Type, target: Type): boolean {
|
||||
return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
|
||||
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
|
||||
source.flags & TypeFlags.TypeVariable ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
|
||||
target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) :
|
||||
hasBaseType(source, getTargetType(target));
|
||||
}
|
||||
@@ -12294,7 +12297,7 @@ namespace ts {
|
||||
// on empty arrays are possible without implicit any errors and new element types can be inferred without
|
||||
// type mismatch errors.
|
||||
const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
return declaredType;
|
||||
}
|
||||
return resultType;
|
||||
@@ -13131,8 +13134,10 @@ namespace ts {
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 ||
|
||||
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
node.parent.kind === SyntaxKind.NonNullExpression ||
|
||||
declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
|
||||
declaration.flags & NodeFlags.Ambient;
|
||||
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
|
||||
type === autoType || type === autoArrayType ? undefinedType :
|
||||
@@ -15572,63 +15577,68 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
||||
const type = checkNonNullExpression(left);
|
||||
if (isTypeAny(type) || type === silentNeverType) {
|
||||
return type;
|
||||
}
|
||||
|
||||
const apparentType = getApparentType(getWidenedType(type));
|
||||
if (apparentType === unknownType || (type.flags & TypeFlags.TypeParameter && isTypeAny(apparentType))) {
|
||||
// handle cases when type is Type parameter with invalid or any constraint
|
||||
let propType: Type;
|
||||
const leftType = checkNonNullExpression(left);
|
||||
const apparentType = getApparentType(getWidenedType(leftType));
|
||||
if (isTypeAny(apparentType) || apparentType === silentNeverType) {
|
||||
return apparentType;
|
||||
}
|
||||
const assignmentKind = getAssignmentTargetKind(node);
|
||||
const prop = getPropertyOfType(apparentType, right.escapedText);
|
||||
if (!prop) {
|
||||
const indexInfo = getIndexInfoOfType(apparentType, IndexKind.String);
|
||||
if (indexInfo && indexInfo.type) {
|
||||
if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) {
|
||||
error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
|
||||
if (!(indexInfo && indexInfo.type)) {
|
||||
if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
|
||||
reportNonexistentProperty(right, leftType.flags & TypeFlags.TypeParameter && (leftType as TypeParameter).isThisType ? apparentType : leftType);
|
||||
}
|
||||
return getFlowTypeOfPropertyAccess(node, /*prop*/ undefined, indexInfo.type, getAssignmentTargetKind(node));
|
||||
}
|
||||
if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
|
||||
reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type);
|
||||
}
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
checkPropertyNotUsedBeforeDeclaration(prop, node, right);
|
||||
|
||||
markPropertyAsReferenced(prop, node, left.kind === SyntaxKind.ThisKeyword);
|
||||
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
|
||||
checkPropertyAccessibility(node, left, apparentType, prop);
|
||||
|
||||
const propType = getDeclaredOrApparentType(prop, node);
|
||||
const assignmentKind = getAssignmentTargetKind(node);
|
||||
|
||||
if (assignmentKind) {
|
||||
if (isReferenceToReadonlyEntity(<Expression>node, prop) || isReferenceThroughNamespaceImport(<Expression>node)) {
|
||||
error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, idText(right));
|
||||
return unknownType;
|
||||
}
|
||||
if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) {
|
||||
error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
|
||||
}
|
||||
propType = indexInfo.type;
|
||||
}
|
||||
return getFlowTypeOfPropertyAccess(node, prop, propType, assignmentKind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only compute control flow type if this is a property access expression that isn't an
|
||||
* assignment target, and the referenced property was declared as a variable, property,
|
||||
* accessor, or optional method.
|
||||
*/
|
||||
function getFlowTypeOfPropertyAccess(node: PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, type: Type, assignmentKind: AssignmentKind) {
|
||||
else {
|
||||
checkPropertyNotUsedBeforeDeclaration(prop, node, right);
|
||||
markPropertyAsReferenced(prop, node, left.kind === SyntaxKind.ThisKeyword);
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
checkPropertyAccessibility(node, left, apparentType, prop);
|
||||
if (assignmentKind) {
|
||||
if (isReferenceToReadonlyEntity(<Expression>node, prop) || isReferenceThroughNamespaceImport(<Expression>node)) {
|
||||
error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, idText(right));
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
propType = getDeclaredOrApparentType(prop, node);
|
||||
}
|
||||
// Only compute control flow type if this is a property access expression that isn't an
|
||||
// assignment target, and the referenced property was declared as a variable, property,
|
||||
// accessor, or optional method.
|
||||
if (node.kind !== SyntaxKind.PropertyAccessExpression ||
|
||||
assignmentKind === AssignmentKind.Definite ||
|
||||
prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && type.flags & TypeFlags.Union)) {
|
||||
return type;
|
||||
prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
|
||||
return propType;
|
||||
}
|
||||
// If strict null checks and strict property initialization checks are enabled, if we have
|
||||
// a this.xxx property access, if the property is an instance property without an initializer,
|
||||
// and if we are in a constructor of the same class as the property declaration, assume that
|
||||
// the property is uninitialized at the top of the control flow.
|
||||
let assumeUninitialized = false;
|
||||
if (strictNullChecks && strictPropertyInitialization && left.kind === SyntaxKind.ThisKeyword) {
|
||||
const declaration = prop && prop.valueDeclaration;
|
||||
if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
|
||||
const flowContainer = getControlFlowContainer(node);
|
||||
if (flowContainer.kind === SyntaxKind.Constructor && flowContainer.parent === declaration.parent) {
|
||||
assumeUninitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
|
||||
if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
error(right, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop));
|
||||
// Return the declared type to reduce follow-on errors
|
||||
return propType;
|
||||
}
|
||||
const flowType = getFlowTypeOfReference(node, type);
|
||||
return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
|
||||
}
|
||||
|
||||
@@ -22494,6 +22504,7 @@ namespace ts {
|
||||
if (produceDiagnostics) {
|
||||
checkIndexConstraints(type);
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
checkPropertyInitialization(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22650,6 +22661,40 @@ namespace ts {
|
||||
return ok;
|
||||
}
|
||||
|
||||
function checkPropertyInitialization(node: ClassLikeDeclaration) {
|
||||
if (!strictNullChecks || !strictPropertyInitialization || node.flags & NodeFlags.Ambient) {
|
||||
return;
|
||||
}
|
||||
const constructor = findConstructorDeclaration(node);
|
||||
for (const member of node.members) {
|
||||
if (isInstancePropertyWithoutInitializer(member)) {
|
||||
const propName = (<PropertyDeclaration>member).name;
|
||||
if (isIdentifier(propName)) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(member));
|
||||
if (!(type.flags & TypeFlags.Any || getFalsyFlags(type) & TypeFlags.Undefined)) {
|
||||
if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
|
||||
error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isInstancePropertyWithoutInitializer(node: Node) {
|
||||
return node.kind === SyntaxKind.PropertyDeclaration &&
|
||||
!hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract) &&
|
||||
!(<PropertyDeclaration>node).exclamationToken &&
|
||||
!(<PropertyDeclaration>node).initializer;
|
||||
}
|
||||
|
||||
function isPropertyInitializedInConstructor(propName: Identifier, propType: Type, constructor: ConstructorDeclaration) {
|
||||
const reference = createPropertyAccess(createThis(), propName);
|
||||
reference.flowNode = constructor.returnFlowNode;
|
||||
const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
|
||||
return !(getFalsyFlags(flowType) & TypeFlags.Undefined);
|
||||
}
|
||||
|
||||
function checkInterfaceDeclaration(node: InterfaceDeclaration) {
|
||||
// Grammar checking
|
||||
if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node);
|
||||
@@ -26072,6 +26117,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.exclamationToken && (node.parent.parent.kind !== SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & NodeFlags.Ambient)) {
|
||||
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
|
||||
}
|
||||
|
||||
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
|
||||
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
|
||||
checkESModuleMarker(node.name);
|
||||
@@ -26235,6 +26284,11 @@ namespace ts {
|
||||
if (node.flags & NodeFlags.Ambient && node.initializer) {
|
||||
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
|
||||
}
|
||||
|
||||
if (node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer ||
|
||||
node.flags & NodeFlags.Ambient || hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract))) {
|
||||
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
|
||||
}
|
||||
}
|
||||
|
||||
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {
|
||||
|
||||
@@ -277,6 +277,13 @@ namespace ts {
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_function_types
|
||||
},
|
||||
{
|
||||
name: "strictPropertyInitialization",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
|
||||
},
|
||||
{
|
||||
name: "noImplicitThis",
|
||||
type: "boolean",
|
||||
|
||||
@@ -1260,10 +1260,12 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function arrayToNumericMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => number): T[] {
|
||||
const result: T[] = [];
|
||||
export function arrayToNumericMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => number): T[];
|
||||
export function arrayToNumericMap<T, V>(array: ReadonlyArray<T>, makeKey: (value: T) => number, makeValue: (value: T) => V): V[];
|
||||
export function arrayToNumericMap<T, V>(array: ReadonlyArray<T>, makeKey: (value: T) => number, makeValue?: (value: T) => V): V[] {
|
||||
const result: V[] = [];
|
||||
for (const value of array) {
|
||||
result[makeKey(value)] = value;
|
||||
result[makeKey(value)] = makeValue ? makeValue(value) : value as any as V;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1967,7 +1969,7 @@ namespace ts {
|
||||
: moduleKind === ModuleKind.System;
|
||||
}
|
||||
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict";
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag];
|
||||
|
||||
@@ -831,6 +831,10 @@
|
||||
"category": "Error",
|
||||
"code": 1254
|
||||
},
|
||||
"A definite assignment assertion '!' is not permitted in this context.": {
|
||||
"category": "Error",
|
||||
"code": 1255
|
||||
},
|
||||
"'with' statements are not allowed in an async function block.": {
|
||||
"category": "Error",
|
||||
"code": 1300
|
||||
@@ -1952,6 +1956,14 @@
|
||||
"category": "Error",
|
||||
"code": 2563
|
||||
},
|
||||
"Property '{0}' has no initializer and is not definitely assigned in the constructor.": {
|
||||
"category": "Error",
|
||||
"code": 2564
|
||||
},
|
||||
"Property '{0}' is used before being assigned.": {
|
||||
"category": "Error",
|
||||
"code": 2565
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -3391,6 +3403,10 @@
|
||||
"category": "Message",
|
||||
"code": 6186
|
||||
},
|
||||
"Enable strict checking of property initialization in classes.": {
|
||||
"category": "Message",
|
||||
"code": 6187
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
+21
-10
@@ -99,6 +99,7 @@ namespace ts {
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).dotDotDotToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).exclamationToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
|
||||
case SyntaxKind.FunctionType:
|
||||
@@ -5251,9 +5252,17 @@ namespace ts {
|
||||
return parseIdentifier();
|
||||
}
|
||||
|
||||
function parseVariableDeclaration(): VariableDeclaration {
|
||||
function parseVariableDeclarationAllowExclamation() {
|
||||
return parseVariableDeclaration(/*allowExclamation*/ true);
|
||||
}
|
||||
|
||||
function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration {
|
||||
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
|
||||
node.name = parseIdentifierOrPattern();
|
||||
if (allowExclamation && node.name.kind === SyntaxKind.Identifier &&
|
||||
token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
node.exclamationToken = parseTokenNode();
|
||||
}
|
||||
node.type = parseTypeAnnotation();
|
||||
if (!isInOrOfKeyword(token())) {
|
||||
node.initializer = parseInitializer();
|
||||
@@ -5295,7 +5304,8 @@ namespace ts {
|
||||
const savedDisallowIn = inDisallowInContext();
|
||||
setDisallowInContext(inForStatementInitializer);
|
||||
|
||||
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, parseVariableDeclaration);
|
||||
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations,
|
||||
inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation);
|
||||
|
||||
setDisallowInContext(savedDisallowIn);
|
||||
}
|
||||
@@ -5346,6 +5356,9 @@ namespace ts {
|
||||
|
||||
function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration {
|
||||
node.kind = SyntaxKind.PropertyDeclaration;
|
||||
if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
node.exclamationToken = parseTokenNode();
|
||||
}
|
||||
node.type = parseTypeAnnotation();
|
||||
|
||||
// For instance properties specifically, since they are evaluated inside the constructor,
|
||||
@@ -6132,16 +6145,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Parses out a JSDoc type expression.
|
||||
export function parseJSDocTypeExpression(): JSDocTypeExpression;
|
||||
export function parseJSDocTypeExpression(requireBraces: true): JSDocTypeExpression | undefined;
|
||||
export function parseJSDocTypeExpression(requireBraces?: boolean): JSDocTypeExpression | undefined {
|
||||
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
|
||||
|
||||
if (!parseExpected(SyntaxKind.OpenBraceToken) && requireBraces) {
|
||||
return undefined;
|
||||
}
|
||||
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
|
||||
result.type = doInsideOfContext(NodeFlags.JSDoc, parseType);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
if (!mayOmitBraces || hasBrace) {
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
|
||||
fixupParentReferences(result);
|
||||
return finishNode(result);
|
||||
@@ -6597,7 +6608,7 @@ namespace ts {
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = parseJSDocTypeExpression(/*requireBraces*/ true);
|
||||
result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -1227,9 +1227,6 @@ namespace ts {
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
if (!sourceFile.additionalSyntacticDiagnostics) {
|
||||
sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile);
|
||||
if (isCheckJsEnabledForFile(sourceFile, options)) {
|
||||
sourceFile.additionalSyntacticDiagnostics = concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.jsDocDiagnostics);
|
||||
}
|
||||
}
|
||||
return concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
|
||||
}
|
||||
@@ -1276,15 +1273,18 @@ namespace ts {
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
|
||||
const isCheckJs = isCheckJsEnabledForFile(sourceFile, options);
|
||||
// By default, only type-check .ts, .tsx, and 'External' files (external files are added by plugins)
|
||||
const includeBindAndCheckDiagnostics = sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX ||
|
||||
sourceFile.scriptKind === ScriptKind.External || isCheckJsEnabledForFile(sourceFile, options);
|
||||
sourceFile.scriptKind === ScriptKind.External || isCheckJs;
|
||||
const bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
|
||||
const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
let diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
if (isCheckJs) {
|
||||
diagnostics = concatenate(diagnostics, sourceFile.jsDocDiagnostics);
|
||||
}
|
||||
return filter(diagnostics, shouldReportDiagnostic);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1873,7 +1873,17 @@ namespace ts {
|
||||
return token = SyntaxKind.CommaToken;
|
||||
case CharacterCodes.dot:
|
||||
pos++;
|
||||
if (text.substr(tokenPos, pos + 2) === "...") {
|
||||
pos += 2;
|
||||
return token = SyntaxKind.DotDotDotToken;
|
||||
}
|
||||
return token = SyntaxKind.DotToken;
|
||||
case CharacterCodes.exclamation:
|
||||
pos++;
|
||||
return token = SyntaxKind.ExclamationToken;
|
||||
case CharacterCodes.question:
|
||||
pos++;
|
||||
return token = SyntaxKind.QuestionToken;
|
||||
}
|
||||
|
||||
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
@@ -1881,6 +1891,7 @@ namespace ts {
|
||||
while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) {
|
||||
pos++;
|
||||
}
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
return token = SyntaxKind.Identifier;
|
||||
}
|
||||
else {
|
||||
|
||||
+10
-4
@@ -598,6 +598,7 @@ namespace ts {
|
||||
|
||||
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
export type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
@@ -761,9 +762,10 @@ namespace ts {
|
||||
export interface VariableDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
name: BindingName; // Declared variable name
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
name: BindingName; // Declared variable name
|
||||
exclamationToken?: ExclamationToken; // Optional definite assignment assertion
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface VariableDeclarationList extends Node {
|
||||
@@ -801,8 +803,9 @@ namespace ts {
|
||||
|
||||
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
@@ -860,6 +863,7 @@ namespace ts {
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -947,6 +951,7 @@ namespace ts {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassDeclaration | ClassExpression;
|
||||
body?: FunctionBody;
|
||||
/* @internal */ returnFlowNode?: FlowNode;
|
||||
}
|
||||
|
||||
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
|
||||
@@ -3854,6 +3859,7 @@ namespace ts {
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean; // Always combine with strict property
|
||||
strictNullChecks?: boolean; // Always combine with strict property
|
||||
strictPropertyInitialization?: boolean; // Always combine with strict property
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
|
||||
@@ -5078,16 +5078,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isStringTextContainingNode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
case SyntaxKind.TemplateTail:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind);
|
||||
}
|
||||
|
||||
// Identifiers
|
||||
|
||||
@@ -208,8 +208,8 @@ namespace Harness.Parallel.Host {
|
||||
workers.push(child);
|
||||
}
|
||||
|
||||
// It's only really worth doing an initial batching if there are a ton of files to go through
|
||||
if (totalFiles > 1000) {
|
||||
// It's only really worth doing an initial batching if there are a ton of files to go through (and they have estimates)
|
||||
if (totalFiles > 1000 && batchSize > 0) {
|
||||
console.log("Batching initial test lists...");
|
||||
const batches: { runner: TestRunnerKind | "unittest", file: string, size: number }[][] = new Array(batchCount);
|
||||
const doneBatching = new Array(batchCount);
|
||||
|
||||
Vendored
+212
-62
@@ -82,8 +82,8 @@ interface ConstrainVideoFacingModeParameters {
|
||||
ideal?: VideoFacingModeEnum | VideoFacingModeEnum[];
|
||||
}
|
||||
|
||||
interface CustomEventInit extends EventInit {
|
||||
detail?: any;
|
||||
interface CustomEventInit<T = any> extends EventInit {
|
||||
detail?: T;
|
||||
}
|
||||
|
||||
interface DeviceAccelerationDict {
|
||||
@@ -696,7 +696,7 @@ interface PaymentDetails {
|
||||
interface PaymentDetailsModifier {
|
||||
additionalDisplayItems?: PaymentItem[];
|
||||
data?: any;
|
||||
supportedMethods: string[];
|
||||
supportedMethods: string | string[];
|
||||
total?: PaymentItem;
|
||||
}
|
||||
|
||||
@@ -708,7 +708,7 @@ interface PaymentItem {
|
||||
|
||||
interface PaymentMethodData {
|
||||
data?: any;
|
||||
supportedMethods: string[];
|
||||
supportedMethods: string | string[];
|
||||
}
|
||||
|
||||
interface PaymentOptions {
|
||||
@@ -1597,6 +1597,7 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods {
|
||||
beginPath(): void;
|
||||
clearRect(x: number, y: number, w: number, h: number): void;
|
||||
clip(fillRule?: CanvasFillRule): void;
|
||||
clip(path: Path2D, fillRule?: CanvasFillRule): void;
|
||||
createImageData(imageDataOrSw: number | ImageData, sh?: number): ImageData;
|
||||
createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
|
||||
createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern;
|
||||
@@ -1606,11 +1607,13 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods {
|
||||
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number, dstW: number, dstH: number): void;
|
||||
drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, srcX: number, srcY: number, srcW: number, srcH: number, dstX: number, dstY: number, dstW: number, dstH: number): void;
|
||||
fill(fillRule?: CanvasFillRule): void;
|
||||
fill(path: Path2D, fillRule?: CanvasFillRule): void;
|
||||
fillRect(x: number, y: number, w: number, h: number): void;
|
||||
fillText(text: string, x: number, y: number, maxWidth?: number): void;
|
||||
getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
|
||||
getLineDash(): number[];
|
||||
isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
||||
isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
||||
measureText(text: string): TextMetrics;
|
||||
putImageData(imagedata: ImageData, dx: number, dy: number, dirtyX?: number, dirtyY?: number, dirtyWidth?: number, dirtyHeight?: number): void;
|
||||
restore(): void;
|
||||
@@ -2374,14 +2377,14 @@ declare var CSSSupportsRule: {
|
||||
new(): CSSSupportsRule;
|
||||
};
|
||||
|
||||
interface CustomEvent extends Event {
|
||||
readonly detail: any;
|
||||
initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: any): void;
|
||||
interface CustomEvent<T = any> extends Event {
|
||||
readonly detail: T;
|
||||
initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: T): void;
|
||||
}
|
||||
|
||||
declare var CustomEvent: {
|
||||
prototype: CustomEvent;
|
||||
new(typeArg: string, eventInitDict?: CustomEventInit): CustomEvent;
|
||||
new<T>(typeArg: string, eventInitDict?: CustomEventInit<T>): CustomEvent<T>;
|
||||
};
|
||||
|
||||
interface DataCue extends TextTrackCue {
|
||||
@@ -3240,7 +3243,8 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven
|
||||
* Retrieves a collection of objects based on the specified element name.
|
||||
* @param name Specifies the name of an element.
|
||||
*/
|
||||
getElementsByTagName<K extends keyof ElementListTagNameMap>(tagname: K): ElementListTagNameMap[K];
|
||||
getElementsByTagName<K extends keyof HTMLElementTagNameMap>(tagname: K): NodeListOf<HTMLElementTagNameMap[K]>;
|
||||
getElementsByTagName<K extends keyof SVGElementTagNameMap>(tagname: K): NodeListOf<SVGElementTagNameMap[K]>;
|
||||
getElementsByTagName(tagname: string): NodeListOf<Element>;
|
||||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
|
||||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
|
||||
@@ -3597,7 +3601,8 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
|
||||
getAttributeNS(namespaceURI: string, localName: string): string;
|
||||
getBoundingClientRect(): ClientRect;
|
||||
getClientRects(): ClientRectList;
|
||||
getElementsByTagName<K extends keyof ElementListTagNameMap>(name: K): ElementListTagNameMap[K];
|
||||
getElementsByTagName<K extends keyof HTMLElementTagNameMap>(name: K): NodeListOf<HTMLElementTagNameMap[K]>;
|
||||
getElementsByTagName<K extends keyof SVGElementTagNameMap>(name: K): NodeListOf<SVGElementTagNameMap[K]>;
|
||||
getElementsByTagName(name: string): NodeListOf<Element>;
|
||||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf<HTMLElement>;
|
||||
getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf<SVGElement>;
|
||||
@@ -3626,6 +3631,8 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
|
||||
webkitRequestFullScreen(): void;
|
||||
getElementsByClassName(classNames: string): NodeListOf<Element>;
|
||||
matches(selector: string): boolean;
|
||||
closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K] | null;
|
||||
closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K] | null;
|
||||
closest(selector: string): Element | null;
|
||||
scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
|
||||
scroll(options?: ScrollToOptions): void;
|
||||
@@ -5520,6 +5527,7 @@ interface HTMLLabelElement extends HTMLElement {
|
||||
* Sets or retrieves the object to which the given label object is assigned.
|
||||
*/
|
||||
htmlFor: string;
|
||||
readonly control: HTMLInputElement | null;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
@@ -9711,7 +9719,7 @@ interface ServiceWorkerContainer extends EventTarget {
|
||||
oncontrollerchange: (this: ServiceWorkerContainer, ev: Event) => any;
|
||||
onmessage: (this: ServiceWorkerContainer, ev: ServiceWorkerMessageEvent) => any;
|
||||
readonly ready: Promise<ServiceWorkerRegistration>;
|
||||
getRegistration(): Promise<ServiceWorkerRegistration | undefined>;
|
||||
getRegistration(clientURL?: USVString): Promise<ServiceWorkerRegistration | undefined>;
|
||||
getRegistrations(): Promise<ServiceWorkerRegistration[]>;
|
||||
register(scriptURL: USVString, options?: RegistrationOptions): Promise<ServiceWorkerRegistration>;
|
||||
addEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -12477,7 +12485,29 @@ interface WebGLRenderingContext {
|
||||
getBufferParameter(target: number, pname: number): any;
|
||||
getContextAttributes(): WebGLContextAttributes;
|
||||
getError(): number;
|
||||
getExtension(name: string): any;
|
||||
getExtension(extensionName: "EXT_blend_minmax"): EXT_blend_minmax | null;
|
||||
getExtension(extensionName: "EXT_texture_filter_anisotropic"): EXT_texture_filter_anisotropic | null;
|
||||
getExtension(extensionName: "EXT_frag_depth"): EXT_frag_depth | null;
|
||||
getExtension(extensionName: "EXT_shader_texture_lod"): EXT_shader_texture_lod | null;
|
||||
getExtension(extensionName: "EXT_sRGB"): EXT_sRGB | null;
|
||||
getExtension(extensionName: "OES_vertex_array_object"): OES_vertex_array_object | null;
|
||||
getExtension(extensionName: "WEBGL_color_buffer_float"): WEBGL_color_buffer_float | null;
|
||||
getExtension(extensionName: "WEBGL_compressed_texture_astc"): WEBGL_compressed_texture_astc | null;
|
||||
getExtension(extensionName: "WEBGL_compressed_texture_s3tc_srgb"): WEBGL_compressed_texture_s3tc_srgb | null;
|
||||
getExtension(extensionName: "WEBGL_debug_shaders"): WEBGL_debug_shaders | null;
|
||||
getExtension(extensionName: "WEBGL_draw_buffers"): WEBGL_draw_buffers | null;
|
||||
getExtension(extensionName: "WEBGL_lose_context"): WEBGL_lose_context | null;
|
||||
getExtension(extensionName: "WEBGL_depth_texture"): WEBGL_depth_texture | null;
|
||||
getExtension(extensionName: "WEBGL_debug_renderer_info"): WEBGL_debug_renderer_info | null;
|
||||
getExtension(extensionName: "WEBGL_compressed_texture_s3tc"): WEBGL_compressed_texture_s3tc | null;
|
||||
getExtension(extensionName: "OES_texture_half_float_linear"): OES_texture_half_float_linear | null;
|
||||
getExtension(extensionName: "OES_texture_half_float"): OES_texture_half_float | null;
|
||||
getExtension(extensionName: "OES_texture_float_linear"): OES_texture_float_linear | null;
|
||||
getExtension(extensionName: "OES_texture_float"): OES_texture_float | null;
|
||||
getExtension(extensionName: "OES_standard_derivatives"): OES_standard_derivatives | null;
|
||||
getExtension(extensionName: "OES_element_index_uint"): OES_element_index_uint | null;
|
||||
getExtension(extensionName: "ANGLE_instanced_arrays"): ANGLE_instanced_arrays | null;
|
||||
getExtension(extensionName: string): any;
|
||||
getFramebufferAttachmentParameter(target: number, attachment: number, pname: number): any;
|
||||
getParameter(pname: number): any;
|
||||
getProgramInfoLog(program: WebGLProgram | null): string | null;
|
||||
@@ -14104,9 +14134,11 @@ interface NavigatorUserMedia {
|
||||
}
|
||||
|
||||
interface NodeSelector {
|
||||
querySelector<K extends keyof ElementTagNameMap>(selectors: K): ElementTagNameMap[K] | null;
|
||||
querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
|
||||
querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
|
||||
querySelector<E extends Element = Element>(selectors: string): E | null;
|
||||
querySelectorAll<K extends keyof ElementListTagNameMap>(selectors: K): ElementListTagNameMap[K];
|
||||
querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
|
||||
querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
|
||||
querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
|
||||
}
|
||||
|
||||
@@ -14625,6 +14657,128 @@ declare var HTMLSummaryElement: {
|
||||
new(): HTMLSummaryElement;
|
||||
};
|
||||
|
||||
interface EXT_blend_minmax {
|
||||
readonly MIN_EXT: number;
|
||||
readonly MAX_EXT: number;
|
||||
}
|
||||
|
||||
interface EXT_frag_depth {
|
||||
}
|
||||
|
||||
interface EXT_shader_texture_lod {
|
||||
}
|
||||
|
||||
interface EXT_sRGB {
|
||||
readonly SRGB_EXT: number;
|
||||
readonly SRGB_ALPHA_EXT: number;
|
||||
readonly SRGB8_ALPHA8_EXT: number;
|
||||
readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: number;
|
||||
}
|
||||
|
||||
interface OES_vertex_array_object {
|
||||
readonly VERTEX_ARRAY_BINDING_OES: number;
|
||||
createVertexArrayOES(): WebGLVertexArrayObjectOES;
|
||||
deleteVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES): void;
|
||||
isVertexArrayOES(value: any): value is WebGLVertexArrayObjectOES;
|
||||
bindVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES): void;
|
||||
}
|
||||
|
||||
interface WebGLVertexArrayObjectOES {
|
||||
}
|
||||
|
||||
interface WEBGL_color_buffer_float {
|
||||
readonly RGBA32F_EXT: number;
|
||||
readonly RGB32F_EXT: number;
|
||||
readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: number;
|
||||
readonly UNSIGNED_NORMALIZED_EXT: number;
|
||||
}
|
||||
|
||||
interface WEBGL_compressed_texture_astc {
|
||||
readonly COMPRESSED_RGBA_ASTC_4x4_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_5x4_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_5x5_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_6x5_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_6x6_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_8x5_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_8x6_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_8x8_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_10x5_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_10x6_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_10x8_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_10x10_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_12x10_KHR: number;
|
||||
readonly COMPRESSED_RGBA_ASTC_12x12_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: number;
|
||||
readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: number;
|
||||
getSupportedProfiles(): string[];
|
||||
}
|
||||
|
||||
interface WEBGL_compressed_texture_s3tc_srgb {
|
||||
readonly COMPRESSED_SRGB_S3TC_DXT1_EXT: number;
|
||||
readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: number;
|
||||
readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: number;
|
||||
readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: number;
|
||||
}
|
||||
|
||||
interface WEBGL_debug_shaders {
|
||||
getTranslatedShaderSource(shader: WebGLShader): string;
|
||||
}
|
||||
|
||||
interface WEBGL_draw_buffers {
|
||||
readonly COLOR_ATTACHMENT0_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT1_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT2_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT3_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT4_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT5_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT6_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT7_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT8_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT9_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT10_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT11_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT12_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT13_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT14_WEBGL: number;
|
||||
readonly COLOR_ATTACHMENT15_WEBGL: number;
|
||||
readonly DRAW_BUFFER0_WEBGL: number;
|
||||
readonly DRAW_BUFFER1_WEBGL: number;
|
||||
readonly DRAW_BUFFER2_WEBGL: number;
|
||||
readonly DRAW_BUFFER3_WEBGL: number;
|
||||
readonly DRAW_BUFFER4_WEBGL: number;
|
||||
readonly DRAW_BUFFER5_WEBGL: number;
|
||||
readonly DRAW_BUFFER6_WEBGL: number;
|
||||
readonly DRAW_BUFFER7_WEBGL: number;
|
||||
readonly DRAW_BUFFER8_WEBGL: number;
|
||||
readonly DRAW_BUFFER9_WEBGL: number;
|
||||
readonly DRAW_BUFFER10_WEBGL: number;
|
||||
readonly DRAW_BUFFER11_WEBGL: number;
|
||||
readonly DRAW_BUFFER12_WEBGL: number;
|
||||
readonly DRAW_BUFFER13_WEBGL: number;
|
||||
readonly DRAW_BUFFER14_WEBGL: number;
|
||||
readonly DRAW_BUFFER15_WEBGL: number;
|
||||
readonly MAX_COLOR_ATTACHMENTS_WEBGL: number;
|
||||
readonly MAX_DRAW_BUFFERS_WEBGL: number;
|
||||
drawBuffersWEBGL(buffers: number[]): void;
|
||||
}
|
||||
|
||||
interface WEBGL_lose_context {
|
||||
loseContext(): void;
|
||||
restoreContext(): void;
|
||||
}
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface DecodeErrorCallback {
|
||||
@@ -14692,28 +14846,46 @@ interface VoidFunction {
|
||||
}
|
||||
interface HTMLElementTagNameMap {
|
||||
"a": HTMLAnchorElement;
|
||||
"abbr": HTMLElement;
|
||||
"acronym": HTMLElement;
|
||||
"address": HTMLElement;
|
||||
"applet": HTMLAppletElement;
|
||||
"area": HTMLAreaElement;
|
||||
"article": HTMLElement;
|
||||
"aside": HTMLElement;
|
||||
"audio": HTMLAudioElement;
|
||||
"b": HTMLElement;
|
||||
"base": HTMLBaseElement;
|
||||
"basefont": HTMLBaseFontElement;
|
||||
"bdo": HTMLElement;
|
||||
"big": HTMLElement;
|
||||
"blockquote": HTMLQuoteElement;
|
||||
"body": HTMLBodyElement;
|
||||
"br": HTMLBRElement;
|
||||
"button": HTMLButtonElement;
|
||||
"canvas": HTMLCanvasElement;
|
||||
"caption": HTMLTableCaptionElement;
|
||||
"center": HTMLElement;
|
||||
"cite": HTMLElement;
|
||||
"code": HTMLElement;
|
||||
"col": HTMLTableColElement;
|
||||
"colgroup": HTMLTableColElement;
|
||||
"data": HTMLDataElement;
|
||||
"datalist": HTMLDataListElement;
|
||||
"dd": HTMLElement;
|
||||
"del": HTMLModElement;
|
||||
"dfn": HTMLElement;
|
||||
"dir": HTMLDirectoryElement;
|
||||
"div": HTMLDivElement;
|
||||
"dl": HTMLDListElement;
|
||||
"dt": HTMLElement;
|
||||
"em": HTMLElement;
|
||||
"embed": HTMLEmbedElement;
|
||||
"fieldset": HTMLFieldSetElement;
|
||||
"figcaption": HTMLElement;
|
||||
"figure": HTMLElement;
|
||||
"font": HTMLFontElement;
|
||||
"footer": HTMLElement;
|
||||
"form": HTMLFormElement;
|
||||
"frame": HTMLFrameElement;
|
||||
"frameset": HTMLFrameSetElement;
|
||||
@@ -14724,24 +14896,34 @@ interface HTMLElementTagNameMap {
|
||||
"h5": HTMLHeadingElement;
|
||||
"h6": HTMLHeadingElement;
|
||||
"head": HTMLHeadElement;
|
||||
"header": HTMLElement;
|
||||
"hgroup": HTMLElement;
|
||||
"hr": HTMLHRElement;
|
||||
"html": HTMLHtmlElement;
|
||||
"i": HTMLElement;
|
||||
"iframe": HTMLIFrameElement;
|
||||
"img": HTMLImageElement;
|
||||
"input": HTMLInputElement;
|
||||
"ins": HTMLModElement;
|
||||
"isindex": HTMLUnknownElement;
|
||||
"kbd": HTMLElement;
|
||||
"keygen": HTMLElement;
|
||||
"label": HTMLLabelElement;
|
||||
"legend": HTMLLegendElement;
|
||||
"li": HTMLLIElement;
|
||||
"link": HTMLLinkElement;
|
||||
"listing": HTMLPreElement;
|
||||
"map": HTMLMapElement;
|
||||
"mark": HTMLElement;
|
||||
"marquee": HTMLMarqueeElement;
|
||||
"menu": HTMLMenuElement;
|
||||
"meta": HTMLMetaElement;
|
||||
"meter": HTMLMeterElement;
|
||||
"nav": HTMLElement;
|
||||
"nextid": HTMLUnknownElement;
|
||||
"nobr": HTMLElement;
|
||||
"noframes": HTMLElement;
|
||||
"noscript": HTMLElement;
|
||||
"object": HTMLObjectElement;
|
||||
"ol": HTMLOListElement;
|
||||
"optgroup": HTMLOptGroupElement;
|
||||
@@ -14750,14 +14932,25 @@ interface HTMLElementTagNameMap {
|
||||
"p": HTMLParagraphElement;
|
||||
"param": HTMLParamElement;
|
||||
"picture": HTMLPictureElement;
|
||||
"plaintext": HTMLElement;
|
||||
"pre": HTMLPreElement;
|
||||
"progress": HTMLProgressElement;
|
||||
"q": HTMLQuoteElement;
|
||||
"rt": HTMLElement;
|
||||
"ruby": HTMLElement;
|
||||
"s": HTMLElement;
|
||||
"samp": HTMLElement;
|
||||
"script": HTMLScriptElement;
|
||||
"section": HTMLElement;
|
||||
"select": HTMLSelectElement;
|
||||
"small": HTMLElement;
|
||||
"source": HTMLSourceElement;
|
||||
"span": HTMLSpanElement;
|
||||
"strike": HTMLElement;
|
||||
"strong": HTMLElement;
|
||||
"style": HTMLStyleElement;
|
||||
"sub": HTMLElement;
|
||||
"sup": HTMLElement;
|
||||
"table": HTMLTableElement;
|
||||
"tbody": HTMLTableSectionElement;
|
||||
"td": HTMLTableDataCellElement;
|
||||
@@ -14770,33 +14963,22 @@ interface HTMLElementTagNameMap {
|
||||
"title": HTMLTitleElement;
|
||||
"tr": HTMLTableRowElement;
|
||||
"track": HTMLTrackElement;
|
||||
"tt": HTMLElement;
|
||||
"u": HTMLElement;
|
||||
"ul": HTMLUListElement;
|
||||
"var": HTMLElement;
|
||||
"video": HTMLVideoElement;
|
||||
"wbr": HTMLElement;
|
||||
"x-ms-webview": MSHTMLWebViewElement;
|
||||
"xmp": HTMLPreElement;
|
||||
}
|
||||
|
||||
interface ElementTagNameMap extends HTMLElementTagNameMap {
|
||||
"abbr": HTMLElement;
|
||||
"acronym": HTMLElement;
|
||||
"address": HTMLElement;
|
||||
"article": HTMLElement;
|
||||
"aside": HTMLElement;
|
||||
"b": HTMLElement;
|
||||
"bdo": HTMLElement;
|
||||
"big": HTMLElement;
|
||||
"center": HTMLElement;
|
||||
interface SVGElementTagNameMap {
|
||||
"circle": SVGCircleElement;
|
||||
"cite": HTMLElement;
|
||||
"clippath": SVGClipPathElement;
|
||||
"code": HTMLElement;
|
||||
"dd": HTMLElement;
|
||||
"defs": SVGDefsElement;
|
||||
"desc": SVGDescElement;
|
||||
"dfn": HTMLElement;
|
||||
"dt": HTMLElement;
|
||||
"ellipse": SVGEllipseElement;
|
||||
"em": HTMLElement;
|
||||
"feblend": SVGFEBlendElement;
|
||||
"fecolormatrix": SVGFEColorMatrixElement;
|
||||
"fecomponenttransfer": SVGFEComponentTransferElement;
|
||||
@@ -14821,64 +15003,32 @@ interface ElementTagNameMap extends HTMLElementTagNameMap {
|
||||
"fespotlight": SVGFESpotLightElement;
|
||||
"fetile": SVGFETileElement;
|
||||
"feturbulence": SVGFETurbulenceElement;
|
||||
"figcaption": HTMLElement;
|
||||
"figure": HTMLElement;
|
||||
"filter": SVGFilterElement;
|
||||
"footer": HTMLElement;
|
||||
"foreignobject": SVGForeignObjectElement;
|
||||
"g": SVGGElement;
|
||||
"header": HTMLElement;
|
||||
"hgroup": HTMLElement;
|
||||
"i": HTMLElement;
|
||||
"image": SVGImageElement;
|
||||
"kbd": HTMLElement;
|
||||
"keygen": HTMLElement;
|
||||
"line": SVGLineElement;
|
||||
"lineargradient": SVGLinearGradientElement;
|
||||
"mark": HTMLElement;
|
||||
"marker": SVGMarkerElement;
|
||||
"mask": SVGMaskElement;
|
||||
"metadata": SVGMetadataElement;
|
||||
"nav": HTMLElement;
|
||||
"nobr": HTMLElement;
|
||||
"noframes": HTMLElement;
|
||||
"noscript": HTMLElement;
|
||||
"path": SVGPathElement;
|
||||
"pattern": SVGPatternElement;
|
||||
"plaintext": HTMLElement;
|
||||
"polygon": SVGPolygonElement;
|
||||
"polyline": SVGPolylineElement;
|
||||
"radialgradient": SVGRadialGradientElement;
|
||||
"rect": SVGRectElement;
|
||||
"rt": HTMLElement;
|
||||
"ruby": HTMLElement;
|
||||
"s": HTMLElement;
|
||||
"samp": HTMLElement;
|
||||
"section": HTMLElement;
|
||||
"small": HTMLElement;
|
||||
"stop": SVGStopElement;
|
||||
"strike": HTMLElement;
|
||||
"strong": HTMLElement;
|
||||
"sub": HTMLElement;
|
||||
"sup": HTMLElement;
|
||||
"svg": SVGSVGElement;
|
||||
"switch": SVGSwitchElement;
|
||||
"symbol": SVGSymbolElement;
|
||||
"text": SVGTextElement;
|
||||
"textpath": SVGTextPathElement;
|
||||
"tspan": SVGTSpanElement;
|
||||
"tt": HTMLElement;
|
||||
"u": HTMLElement;
|
||||
"use": SVGUseElement;
|
||||
"var": HTMLElement;
|
||||
"view": SVGViewElement;
|
||||
"wbr": HTMLElement;
|
||||
}
|
||||
|
||||
type ElementListTagNameMap = {
|
||||
[key in keyof ElementTagNameMap]: NodeListOf<ElementTagNameMap[key]>
|
||||
};
|
||||
|
||||
declare var Audio: { new(src?: string): HTMLAudioElement; };
|
||||
declare var Image: { new(width?: number, height?: number): HTMLImageElement; };
|
||||
declare var Option: { new(text?: string, value?: string, defaultSelected?: boolean, selected?: boolean): HTMLOptionElement; };
|
||||
|
||||
+345
-366
@@ -1,177 +1,50 @@
|
||||
namespace ts {
|
||||
/// Classifier
|
||||
export function createClassifier(): Classifier {
|
||||
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
|
||||
|
||||
/// We do not have a full parser support to know when we should parse a regex or not
|
||||
/// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
|
||||
/// we have a series of divide operator. this list allows us to be more accurate by ruling out
|
||||
/// locations where a regexp cannot exist.
|
||||
const noRegexTable: boolean[] = [];
|
||||
noRegexTable[SyntaxKind.Identifier] = true;
|
||||
noRegexTable[SyntaxKind.StringLiteral] = true;
|
||||
noRegexTable[SyntaxKind.NumericLiteral] = true;
|
||||
noRegexTable[SyntaxKind.RegularExpressionLiteral] = true;
|
||||
noRegexTable[SyntaxKind.ThisKeyword] = true;
|
||||
noRegexTable[SyntaxKind.PlusPlusToken] = true;
|
||||
noRegexTable[SyntaxKind.MinusMinusToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseParenToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBracketToken] = true;
|
||||
noRegexTable[SyntaxKind.CloseBraceToken] = true;
|
||||
noRegexTable[SyntaxKind.TrueKeyword] = true;
|
||||
noRegexTable[SyntaxKind.FalseKeyword] = true;
|
||||
|
||||
// Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
|
||||
// classification on template strings. Because of the context free nature of templates,
|
||||
// the only precise way to classify a template portion would be by propagating the stack across
|
||||
// lines, just as we do with the end-of-line state. However, this is a burden for implementers,
|
||||
// and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
|
||||
// flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
|
||||
// Situations in which this fails are
|
||||
// 1) When template strings are nested across different lines:
|
||||
// `hello ${ `world
|
||||
// ` }`
|
||||
//
|
||||
// Where on the second line, you will get the closing of a template,
|
||||
// a closing curly, and a new template.
|
||||
//
|
||||
// 2) When substitution expressions have curly braces and the curly brace falls on the next line:
|
||||
// `hello ${ () => {
|
||||
// return "world" } } `
|
||||
//
|
||||
// Where on the second line, you will get the 'return' keyword,
|
||||
// a string literal, and a template end consisting of '} } `'.
|
||||
const templateStack: SyntaxKind[] = [];
|
||||
|
||||
/** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
|
||||
function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) {
|
||||
if (isAccessibilityModifier(keyword1)) {
|
||||
if (keyword2 === SyntaxKind.GetKeyword ||
|
||||
keyword2 === SyntaxKind.SetKeyword ||
|
||||
keyword2 === SyntaxKind.ConstructorKeyword ||
|
||||
keyword2 === SyntaxKind.StaticKeyword) {
|
||||
|
||||
// Allow things like "public get", "public constructor" and "public static".
|
||||
// These are all legal.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any other keyword following "public" is actually an identifier an not a real
|
||||
// keyword.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume any other keyword combination is legal. This can be refined in the future
|
||||
// if there are more cases we want the classifier to be better at.
|
||||
return true;
|
||||
}
|
||||
|
||||
function convertClassifications(classifications: Classifications, text: string): ClassificationResult {
|
||||
const entries: ClassificationInfo[] = [];
|
||||
const dense = classifications.spans;
|
||||
let lastEnd = 0;
|
||||
|
||||
for (let i = 0; i < dense.length; i += 3) {
|
||||
const start = dense[i];
|
||||
const length = dense[i + 1];
|
||||
const type = <ClassificationType>dense[i + 2];
|
||||
|
||||
// Make a whitespace entry between the last item and this one.
|
||||
if (lastEnd >= 0) {
|
||||
const whitespaceLength = start - lastEnd;
|
||||
if (whitespaceLength > 0) {
|
||||
entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace });
|
||||
}
|
||||
}
|
||||
|
||||
entries.push({ length, classification: convertClassification(type) });
|
||||
lastEnd = start + length;
|
||||
}
|
||||
|
||||
const whitespaceLength = text.length - lastEnd;
|
||||
if (whitespaceLength > 0) {
|
||||
entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace });
|
||||
}
|
||||
|
||||
return { entries, finalLexState: classifications.endOfLineState };
|
||||
}
|
||||
|
||||
function convertClassification(type: ClassificationType): TokenClass {
|
||||
switch (type) {
|
||||
case ClassificationType.comment: return TokenClass.Comment;
|
||||
case ClassificationType.keyword: return TokenClass.Keyword;
|
||||
case ClassificationType.numericLiteral: return TokenClass.NumberLiteral;
|
||||
case ClassificationType.operator: return TokenClass.Operator;
|
||||
case ClassificationType.stringLiteral: return TokenClass.StringLiteral;
|
||||
case ClassificationType.whiteSpace: return TokenClass.Whitespace;
|
||||
case ClassificationType.punctuation: return TokenClass.Punctuation;
|
||||
case ClassificationType.identifier:
|
||||
case ClassificationType.className:
|
||||
case ClassificationType.enumName:
|
||||
case ClassificationType.interfaceName:
|
||||
case ClassificationType.moduleName:
|
||||
case ClassificationType.typeParameterName:
|
||||
case ClassificationType.typeAliasName:
|
||||
case ClassificationType.text:
|
||||
case ClassificationType.parameterName:
|
||||
default:
|
||||
return TokenClass.Identifier;
|
||||
}
|
||||
}
|
||||
|
||||
function getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent: boolean): ClassificationResult {
|
||||
return convertClassifications(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
|
||||
return convertClassificationsToResult(getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent), text);
|
||||
}
|
||||
|
||||
// If there is a syntactic classifier ('syntacticClassifierAbsent' is false),
|
||||
// we will be more conservative in order to avoid conflicting with the syntactic classifier.
|
||||
function getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent: boolean): Classifications {
|
||||
let offset = 0;
|
||||
let token = SyntaxKind.Unknown;
|
||||
let lastNonTriviaToken = SyntaxKind.Unknown;
|
||||
|
||||
// Empty out the template stack for reuse.
|
||||
while (templateStack.length > 0) {
|
||||
templateStack.pop();
|
||||
}
|
||||
|
||||
// If we're in a string literal, then prepend: "\
|
||||
// (and a newline). That way when we lex we'll think we're still in a string literal.
|
||||
// Just a stack of TemplateHeads and OpenCurlyBraces, used to perform rudimentary (inexact)
|
||||
// classification on template strings. Because of the context free nature of templates,
|
||||
// the only precise way to classify a template portion would be by propagating the stack across
|
||||
// lines, just as we do with the end-of-line state. However, this is a burden for implementers,
|
||||
// and the behavior is entirely subsumed by the syntactic classifier anyway, so we instead
|
||||
// flatten any nesting when the template stack is non-empty and encode it in the end-of-line state.
|
||||
// Situations in which this fails are
|
||||
// 1) When template strings are nested across different lines:
|
||||
// `hello ${ `world
|
||||
// ` }`
|
||||
//
|
||||
// If we're in a multiline comment, then prepend: /*
|
||||
// (and a newline). That way when we lex we'll think we're still in a multiline comment.
|
||||
switch (lexState) {
|
||||
case EndOfLineState.InDoubleQuoteStringLiteral:
|
||||
text = "\"\\\n" + text;
|
||||
offset = 3;
|
||||
break;
|
||||
case EndOfLineState.InSingleQuoteStringLiteral:
|
||||
text = "'\\\n" + text;
|
||||
offset = 3;
|
||||
break;
|
||||
case EndOfLineState.InMultiLineCommentTrivia:
|
||||
text = "/*\n" + text;
|
||||
offset = 3;
|
||||
break;
|
||||
case EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate:
|
||||
text = "`\n" + text;
|
||||
offset = 2;
|
||||
break;
|
||||
case EndOfLineState.InTemplateMiddleOrTail:
|
||||
text = "}\n" + text;
|
||||
offset = 2;
|
||||
// falls through
|
||||
case EndOfLineState.InTemplateSubstitutionPosition:
|
||||
templateStack.push(SyntaxKind.TemplateHead);
|
||||
break;
|
||||
// Where on the second line, you will get the closing of a template,
|
||||
// a closing curly, and a new template.
|
||||
//
|
||||
// 2) When substitution expressions have curly braces and the curly brace falls on the next line:
|
||||
// `hello ${ () => {
|
||||
// return "world" } } `
|
||||
//
|
||||
// Where on the second line, you will get the 'return' keyword,
|
||||
// a string literal, and a template end consisting of '} } `'.
|
||||
const templateStack: SyntaxKind[] = [];
|
||||
|
||||
const { prefix, pushTemplate } = getPrefixFromLexState(lexState);
|
||||
text = prefix + text;
|
||||
const offset = prefix.length;
|
||||
if (pushTemplate) {
|
||||
templateStack.push(SyntaxKind.TemplateHead);
|
||||
}
|
||||
|
||||
scanner.setText(text);
|
||||
|
||||
const result: Classifications = {
|
||||
endOfLineState: EndOfLineState.None,
|
||||
spans: []
|
||||
};
|
||||
let endOfLineState = EndOfLineState.None;
|
||||
const spans: number[] = [];
|
||||
|
||||
// We can run into an unfortunate interaction between the lexical and syntactic classifier
|
||||
// when the user is typing something generic. Consider the case where the user types:
|
||||
@@ -196,57 +69,65 @@ namespace ts {
|
||||
|
||||
do {
|
||||
token = scanner.scan();
|
||||
|
||||
if (!isTrivia(token)) {
|
||||
if ((token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) && !noRegexTable[lastNonTriviaToken]) {
|
||||
if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
|
||||
handleToken();
|
||||
lastNonTriviaToken = token;
|
||||
}
|
||||
const end = scanner.getTextPos();
|
||||
pushEncodedClassification(scanner.getTokenPos(), end, offset, classFromKind(token), spans);
|
||||
if (end >= text.length) {
|
||||
const end = getNewEndOfLineState(scanner, token, lastOrUndefined(templateStack));
|
||||
if (end !== undefined) {
|
||||
endOfLineState = end;
|
||||
}
|
||||
}
|
||||
} while (token !== SyntaxKind.EndOfFileToken);
|
||||
|
||||
function handleToken(): void {
|
||||
switch (token) {
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.SlashEqualsToken:
|
||||
if (!noRegexTable[lastNonTriviaToken] && scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
|
||||
token = SyntaxKind.RegularExpressionLiteral;
|
||||
}
|
||||
}
|
||||
else if (lastNonTriviaToken === SyntaxKind.DotToken && isKeyword(token)) {
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
|
||||
// We have two keywords in a row. Only treat the second as a keyword if
|
||||
// it's a sequence that could legally occur in the language. Otherwise
|
||||
// treat it as an identifier. This way, if someone writes "private var"
|
||||
// we recognize that 'var' is actually an identifier here.
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
else if (lastNonTriviaToken === SyntaxKind.Identifier &&
|
||||
token === SyntaxKind.LessThanToken) {
|
||||
// Could be the start of something generic. Keep track of that by bumping
|
||||
// up the current count of generic contexts we may be in.
|
||||
angleBracketStack++;
|
||||
}
|
||||
else if (token === SyntaxKind.GreaterThanToken && angleBracketStack > 0) {
|
||||
// If we think we're currently in something generic, then mark that that
|
||||
// generic entity is complete.
|
||||
angleBracketStack--;
|
||||
}
|
||||
else if (token === SyntaxKind.AnyKeyword ||
|
||||
token === SyntaxKind.StringKeyword ||
|
||||
token === SyntaxKind.NumberKeyword ||
|
||||
token === SyntaxKind.BooleanKeyword ||
|
||||
token === SyntaxKind.SymbolKeyword) {
|
||||
break;
|
||||
case SyntaxKind.LessThanToken:
|
||||
if (lastNonTriviaToken === SyntaxKind.Identifier) {
|
||||
// Could be the start of something generic. Keep track of that by bumping
|
||||
// up the current count of generic contexts we may be in.
|
||||
angleBracketStack++;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.GreaterThanToken:
|
||||
if (angleBracketStack > 0) {
|
||||
// If we think we're currently in something generic, then mark that that
|
||||
// generic entity is complete.
|
||||
angleBracketStack--;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
|
||||
// If it looks like we're could be in something generic, don't classify this
|
||||
// as a keyword. We may just get overwritten by the syntactic classifier,
|
||||
// causing a noisy experience for the user.
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.TemplateHead) {
|
||||
break;
|
||||
case SyntaxKind.TemplateHead:
|
||||
templateStack.push(token);
|
||||
}
|
||||
else if (token === SyntaxKind.OpenBraceToken) {
|
||||
break;
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
// If we don't have anything on the template stack,
|
||||
// then we aren't trying to keep track of a previously scanned template head.
|
||||
if (templateStack.length > 0) {
|
||||
templateStack.push(token);
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.CloseBraceToken) {
|
||||
break;
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
// If we don't have anything on the template stack,
|
||||
// then we aren't trying to keep track of a previously scanned template head.
|
||||
if (templateStack.length > 0) {
|
||||
@@ -268,202 +149,300 @@ namespace ts {
|
||||
templateStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastNonTriviaToken = token;
|
||||
}
|
||||
|
||||
processToken();
|
||||
}
|
||||
while (token !== SyntaxKind.EndOfFileToken);
|
||||
|
||||
return result;
|
||||
|
||||
function processToken(): void {
|
||||
const start = scanner.getTokenPos();
|
||||
const end = scanner.getTextPos();
|
||||
|
||||
addResult(start, end, classFromKind(token));
|
||||
|
||||
if (end >= text.length) {
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// Check to see if we finished up on a multiline string literal.
|
||||
const tokenText = scanner.getTokenText();
|
||||
if (scanner.isUnterminated()) {
|
||||
const lastCharIndex = tokenText.length - 1;
|
||||
|
||||
let numBackslashes = 0;
|
||||
while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) {
|
||||
numBackslashes++;
|
||||
}
|
||||
|
||||
// If we have an odd number of backslashes, then the multiline string is unclosed
|
||||
if (numBackslashes & 1) {
|
||||
const quoteChar = tokenText.charCodeAt(0);
|
||||
result.endOfLineState = quoteChar === CharacterCodes.doubleQuote
|
||||
? EndOfLineState.InDoubleQuoteStringLiteral
|
||||
: EndOfLineState.InSingleQuoteStringLiteral;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!isKeyword(token)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.MultiLineCommentTrivia) {
|
||||
// Check to see if the multiline comment was unclosed.
|
||||
if (scanner.isUnterminated()) {
|
||||
result.endOfLineState = EndOfLineState.InMultiLineCommentTrivia;
|
||||
|
||||
if (lastNonTriviaToken === SyntaxKind.DotToken) {
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
}
|
||||
else if (isTemplateLiteralKind(token)) {
|
||||
if (scanner.isUnterminated()) {
|
||||
if (token === SyntaxKind.TemplateTail) {
|
||||
result.endOfLineState = EndOfLineState.InTemplateMiddleOrTail;
|
||||
}
|
||||
else if (token === SyntaxKind.NoSubstitutionTemplateLiteral) {
|
||||
result.endOfLineState = EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
|
||||
}
|
||||
else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
|
||||
// We have two keywords in a row. Only treat the second as a keyword if
|
||||
// it's a sequence that could legally occur in the language. Otherwise
|
||||
// treat it as an identifier. This way, if someone writes "private var"
|
||||
// we recognize that 'var' is actually an identifier here.
|
||||
token = SyntaxKind.Identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { endOfLineState, spans };
|
||||
}
|
||||
|
||||
return { getClassificationsForLine, getEncodedLexicalClassifications };
|
||||
}
|
||||
|
||||
/// We do not have a full parser support to know when we should parse a regex or not
|
||||
/// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
|
||||
/// we have a series of divide operator. this list allows us to be more accurate by ruling out
|
||||
/// locations where a regexp cannot exist.
|
||||
const noRegexTable: true[] = ts.arrayToNumericMap<SyntaxKind, true>([
|
||||
SyntaxKind.Identifier,
|
||||
SyntaxKind.StringLiteral,
|
||||
SyntaxKind.NumericLiteral,
|
||||
SyntaxKind.RegularExpressionLiteral,
|
||||
SyntaxKind.ThisKeyword,
|
||||
SyntaxKind.PlusPlusToken,
|
||||
SyntaxKind.MinusMinusToken,
|
||||
SyntaxKind.CloseParenToken,
|
||||
SyntaxKind.CloseBracketToken,
|
||||
SyntaxKind.CloseBraceToken,
|
||||
SyntaxKind.TrueKeyword,
|
||||
SyntaxKind.FalseKeyword,
|
||||
], token => token, () => true);
|
||||
|
||||
function getNewEndOfLineState(scanner: Scanner, token: SyntaxKind, lastOnTemplateStack: SyntaxKind | undefined): EndOfLineState | undefined {
|
||||
switch (token) {
|
||||
case SyntaxKind.StringLiteral: {
|
||||
// Check to see if we finished up on a multiline string literal.
|
||||
if (!scanner.isUnterminated()) return undefined;
|
||||
|
||||
const tokenText = scanner.getTokenText();
|
||||
const lastCharIndex = tokenText.length - 1;
|
||||
let numBackslashes = 0;
|
||||
while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) {
|
||||
numBackslashes++;
|
||||
}
|
||||
|
||||
// If we have an odd number of backslashes, then the multiline string is unclosed
|
||||
if ((numBackslashes & 1) === 0) return undefined;
|
||||
return tokenText.charCodeAt(0) === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral;
|
||||
}
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
// Check to see if the multiline comment was unclosed.
|
||||
return scanner.isUnterminated() ? EndOfLineState.InMultiLineCommentTrivia : undefined;
|
||||
default:
|
||||
if (isTemplateLiteralKind(token)) {
|
||||
if (!scanner.isUnterminated()) {
|
||||
return undefined;
|
||||
}
|
||||
else if (templateStack.length > 0 && lastOrUndefined(templateStack) === SyntaxKind.TemplateHead) {
|
||||
result.endOfLineState = EndOfLineState.InTemplateSubstitutionPosition;
|
||||
switch (token) {
|
||||
case SyntaxKind.TemplateTail:
|
||||
return EndOfLineState.InTemplateMiddleOrTail;
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate;
|
||||
default:
|
||||
throw Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lastOnTemplateStack === SyntaxKind.TemplateHead ? EndOfLineState.InTemplateSubstitutionPosition : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function addResult(start: number, end: number, classification: ClassificationType): void {
|
||||
if (classification === ClassificationType.whiteSpace) {
|
||||
// Don't bother with whitespace classifications. They're not needed.
|
||||
return;
|
||||
}
|
||||
function pushEncodedClassification(start: number, end: number, offset: number, classification: ClassificationType, result: Push<number>): void {
|
||||
if (classification === ClassificationType.whiteSpace) {
|
||||
// Don't bother with whitespace classifications. They're not needed.
|
||||
return;
|
||||
}
|
||||
|
||||
if (start === 0 && offset > 0) {
|
||||
// We're classifying the first token, and this was a case where we prepended
|
||||
// text. We should consider the start of this token to be at the start of
|
||||
// the original text.
|
||||
start += offset;
|
||||
}
|
||||
if (start === 0 && offset > 0) {
|
||||
// We're classifying the first token, and this was a case where we prepended text.
|
||||
// We should consider the start of this token to be at the start of the original text.
|
||||
start += offset;
|
||||
}
|
||||
|
||||
// All our tokens are in relation to the augmented text. Move them back to be
|
||||
// relative to the original text.
|
||||
start -= offset;
|
||||
end -= offset;
|
||||
const length = end - start;
|
||||
const length = end - start;
|
||||
if (length > 0) {
|
||||
// All our tokens are in relation to the augmented text. Move them back to be
|
||||
// relative to the original text.
|
||||
result.push(start - offset, length, classification);
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
result.spans.push(start);
|
||||
result.spans.push(length);
|
||||
result.spans.push(classification);
|
||||
function convertClassificationsToResult(classifications: Classifications, text: string): ClassificationResult {
|
||||
const entries: ClassificationInfo[] = [];
|
||||
const dense = classifications.spans;
|
||||
let lastEnd = 0;
|
||||
|
||||
for (let i = 0; i < dense.length; i += 3) {
|
||||
const start = dense[i];
|
||||
const length = dense[i + 1];
|
||||
const type = <ClassificationType>dense[i + 2];
|
||||
|
||||
// Make a whitespace entry between the last item and this one.
|
||||
if (lastEnd >= 0) {
|
||||
const whitespaceLength = start - lastEnd;
|
||||
if (whitespaceLength > 0) {
|
||||
entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace });
|
||||
}
|
||||
}
|
||||
|
||||
entries.push({ length, classification: convertClassification(type) });
|
||||
lastEnd = start + length;
|
||||
}
|
||||
|
||||
function isBinaryExpressionOperatorToken(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.PercentToken:
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.LessThanLessThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
case SyntaxKind.GreaterThanToken:
|
||||
case SyntaxKind.LessThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanEqualsToken:
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
case SyntaxKind.InKeyword:
|
||||
case SyntaxKind.AsKeyword:
|
||||
case SyntaxKind.EqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
case SyntaxKind.AmpersandToken:
|
||||
case SyntaxKind.CaretToken:
|
||||
case SyntaxKind.BarToken:
|
||||
case SyntaxKind.AmpersandAmpersandToken:
|
||||
case SyntaxKind.BarBarToken:
|
||||
case SyntaxKind.BarEqualsToken:
|
||||
case SyntaxKind.AmpersandEqualsToken:
|
||||
case SyntaxKind.CaretEqualsToken:
|
||||
case SyntaxKind.LessThanLessThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.PlusEqualsToken:
|
||||
case SyntaxKind.MinusEqualsToken:
|
||||
case SyntaxKind.AsteriskEqualsToken:
|
||||
case SyntaxKind.SlashEqualsToken:
|
||||
case SyntaxKind.PercentEqualsToken:
|
||||
case SyntaxKind.EqualsToken:
|
||||
case SyntaxKind.CommaToken:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
const whitespaceLength = text.length - lastEnd;
|
||||
if (whitespaceLength > 0) {
|
||||
entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace });
|
||||
}
|
||||
|
||||
function isPrefixUnaryExpressionOperatorToken(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.TildeToken:
|
||||
case SyntaxKind.ExclamationToken:
|
||||
case SyntaxKind.PlusPlusToken:
|
||||
case SyntaxKind.MinusMinusToken:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return { entries, finalLexState: classifications.endOfLineState };
|
||||
}
|
||||
|
||||
function convertClassification(type: ClassificationType): TokenClass {
|
||||
switch (type) {
|
||||
case ClassificationType.comment: return TokenClass.Comment;
|
||||
case ClassificationType.keyword: return TokenClass.Keyword;
|
||||
case ClassificationType.numericLiteral: return TokenClass.NumberLiteral;
|
||||
case ClassificationType.operator: return TokenClass.Operator;
|
||||
case ClassificationType.stringLiteral: return TokenClass.StringLiteral;
|
||||
case ClassificationType.whiteSpace: return TokenClass.Whitespace;
|
||||
case ClassificationType.punctuation: return TokenClass.Punctuation;
|
||||
case ClassificationType.identifier:
|
||||
case ClassificationType.className:
|
||||
case ClassificationType.enumName:
|
||||
case ClassificationType.interfaceName:
|
||||
case ClassificationType.moduleName:
|
||||
case ClassificationType.typeParameterName:
|
||||
case ClassificationType.typeAliasName:
|
||||
case ClassificationType.text:
|
||||
case ClassificationType.parameterName:
|
||||
return TokenClass.Identifier;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */
|
||||
function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind): boolean {
|
||||
if (!isAccessibilityModifier(keyword1)) {
|
||||
// Assume any other keyword combination is legal.
|
||||
// This can be refined in the future if there are more cases we want the classifier to be better at.
|
||||
return true;
|
||||
}
|
||||
switch (keyword2) {
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
return true; // Allow things like "public get", "public constructor" and "public static".
|
||||
default:
|
||||
return false; // Any other keyword following "public" is actually an identifier, not a real keyword.
|
||||
}
|
||||
}
|
||||
|
||||
function getPrefixFromLexState(lexState: EndOfLineState): { readonly prefix: string, readonly pushTemplate?: true } {
|
||||
// If we're in a string literal, then prepend: "\
|
||||
// (and a newline). That way when we lex we'll think we're still in a string literal.
|
||||
//
|
||||
// If we're in a multiline comment, then prepend: /*
|
||||
// (and a newline). That way when we lex we'll think we're still in a multiline comment.
|
||||
switch (lexState) {
|
||||
case EndOfLineState.InDoubleQuoteStringLiteral:
|
||||
return { prefix: "\"\\\n" };
|
||||
case EndOfLineState.InSingleQuoteStringLiteral:
|
||||
return { prefix: "'\\\n" };
|
||||
case EndOfLineState.InMultiLineCommentTrivia:
|
||||
return { prefix: "/*\n" };
|
||||
case EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate:
|
||||
return { prefix: "`\n" };
|
||||
case EndOfLineState.InTemplateMiddleOrTail:
|
||||
return { prefix: "}\n", pushTemplate: true };
|
||||
case EndOfLineState.InTemplateSubstitutionPosition:
|
||||
return { prefix: "", pushTemplate: true };
|
||||
case EndOfLineState.None:
|
||||
return { prefix: "" };
|
||||
default:
|
||||
throw Debug.assertNever(lexState);
|
||||
}
|
||||
}
|
||||
|
||||
function isBinaryExpressionOperatorToken(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.PercentToken:
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.LessThanLessThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
case SyntaxKind.GreaterThanToken:
|
||||
case SyntaxKind.LessThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanEqualsToken:
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
case SyntaxKind.InKeyword:
|
||||
case SyntaxKind.AsKeyword:
|
||||
case SyntaxKind.EqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
case SyntaxKind.AmpersandToken:
|
||||
case SyntaxKind.CaretToken:
|
||||
case SyntaxKind.BarToken:
|
||||
case SyntaxKind.AmpersandAmpersandToken:
|
||||
case SyntaxKind.BarBarToken:
|
||||
case SyntaxKind.BarEqualsToken:
|
||||
case SyntaxKind.AmpersandEqualsToken:
|
||||
case SyntaxKind.CaretEqualsToken:
|
||||
case SyntaxKind.LessThanLessThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.PlusEqualsToken:
|
||||
case SyntaxKind.MinusEqualsToken:
|
||||
case SyntaxKind.AsteriskEqualsToken:
|
||||
case SyntaxKind.SlashEqualsToken:
|
||||
case SyntaxKind.PercentEqualsToken:
|
||||
case SyntaxKind.EqualsToken:
|
||||
case SyntaxKind.CommaToken:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isPrefixUnaryExpressionOperatorToken(token: SyntaxKind): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.TildeToken:
|
||||
case SyntaxKind.ExclamationToken:
|
||||
case SyntaxKind.PlusPlusToken:
|
||||
case SyntaxKind.MinusMinusToken:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function classFromKind(token: SyntaxKind): ClassificationType {
|
||||
if (isKeyword(token)) {
|
||||
return ClassificationType.keyword;
|
||||
}
|
||||
else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
|
||||
return ClassificationType.operator;
|
||||
}
|
||||
else if (token >= SyntaxKind.FirstPunctuation && token <= SyntaxKind.LastPunctuation) {
|
||||
return ClassificationType.punctuation;
|
||||
}
|
||||
|
||||
function isKeyword(token: SyntaxKind): boolean {
|
||||
return token >= SyntaxKind.FirstKeyword && token <= SyntaxKind.LastKeyword;
|
||||
}
|
||||
|
||||
function classFromKind(token: SyntaxKind): ClassificationType {
|
||||
if (isKeyword(token)) {
|
||||
return ClassificationType.keyword;
|
||||
}
|
||||
else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
|
||||
return ClassificationType.operator;
|
||||
}
|
||||
else if (token >= SyntaxKind.FirstPunctuation && token <= SyntaxKind.LastPunctuation) {
|
||||
return ClassificationType.punctuation;
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return ClassificationType.numericLiteral;
|
||||
case SyntaxKind.StringLiteral:
|
||||
switch (token) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return ClassificationType.numericLiteral;
|
||||
case SyntaxKind.StringLiteral:
|
||||
return ClassificationType.stringLiteral;
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return ClassificationType.regularExpressionLiteral;
|
||||
case SyntaxKind.ConflictMarkerTrivia:
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
return ClassificationType.comment;
|
||||
case SyntaxKind.WhitespaceTrivia:
|
||||
case SyntaxKind.NewLineTrivia:
|
||||
return ClassificationType.whiteSpace;
|
||||
case SyntaxKind.Identifier:
|
||||
default:
|
||||
if (isTemplateLiteralKind(token)) {
|
||||
return ClassificationType.stringLiteral;
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return ClassificationType.regularExpressionLiteral;
|
||||
case SyntaxKind.ConflictMarkerTrivia:
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
return ClassificationType.comment;
|
||||
case SyntaxKind.WhitespaceTrivia:
|
||||
case SyntaxKind.NewLineTrivia:
|
||||
return ClassificationType.whiteSpace;
|
||||
case SyntaxKind.Identifier:
|
||||
default:
|
||||
if (isTemplateLiteralKind(token)) {
|
||||
return ClassificationType.stringLiteral;
|
||||
}
|
||||
return ClassificationType.identifier;
|
||||
}
|
||||
}
|
||||
return ClassificationType.identifier;
|
||||
}
|
||||
|
||||
return {
|
||||
getClassificationsForLine,
|
||||
getEncodedLexicalClassifications
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: UnderscoreEscapedMap<true>, span: TextSpan): ClassifiedSpan[] {
|
||||
return convertClassifications(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
|
||||
return convertClassificationsToSpans(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
|
||||
}
|
||||
|
||||
function checkForClassificationCancellation(cancellationToken: CancellationToken, kind: SyntaxKind) {
|
||||
@@ -583,7 +562,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function convertClassifications(classifications: Classifications): ClassifiedSpan[] {
|
||||
function convertClassificationsToSpans(classifications: Classifications): ClassifiedSpan[] {
|
||||
Debug.assert(classifications.spans.length % 3 === 0);
|
||||
const dense = classifications.spans;
|
||||
const result: ClassifiedSpan[] = [];
|
||||
@@ -599,7 +578,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function getSyntacticClassifications(cancellationToken: CancellationToken, sourceFile: SourceFile, span: TextSpan): ClassifiedSpan[] {
|
||||
return convertClassifications(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
|
||||
return convertClassificationsToSpans(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
+6
-1
@@ -461,6 +461,7 @@ declare namespace ts {
|
||||
}
|
||||
type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
@@ -537,6 +538,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
name: BindingName;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -571,8 +573,9 @@ declare namespace ts {
|
||||
}
|
||||
interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken;
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -606,6 +609,7 @@ declare namespace ts {
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -2287,6 +2291,7 @@ declare namespace ts {
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
|
||||
+6
-1
@@ -461,6 +461,7 @@ declare namespace ts {
|
||||
}
|
||||
type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
@@ -537,6 +538,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
name: BindingName;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -571,8 +573,9 @@ declare namespace ts {
|
||||
}
|
||||
interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken;
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -606,6 +609,7 @@ declare namespace ts {
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
@@ -2287,6 +2291,7 @@ declare namespace ts {
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(5,5): error TS2564: Property 'b' has no initializer and is not definitely assigned in the constructor.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(20,6): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(21,6): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(22,13): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(28,6): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(34,15): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(68,10): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(69,10): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(70,10): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(75,15): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts(76,15): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts (11 errors) ====
|
||||
// Suppress strict property initialization check
|
||||
|
||||
class C1 {
|
||||
a!: number;
|
||||
b: string; // Error
|
||||
~
|
||||
!!! error TS2564: Property 'b' has no initializer and is not definitely assigned in the constructor.
|
||||
}
|
||||
|
||||
// Suppress definite assignment check in constructor
|
||||
|
||||
class C2 {
|
||||
a!: number;
|
||||
constructor() {
|
||||
let x = this.a;
|
||||
}
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
|
||||
class C3 {
|
||||
a! = 1;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
b!: number = 1;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
static c!: number;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare class C4 {
|
||||
a!: number;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
|
||||
abstract class C5 {
|
||||
abstract a!: number;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
}
|
||||
|
||||
// Suppress definite assignment check for variable
|
||||
|
||||
function f1() {
|
||||
let x!: number;
|
||||
let y = x;
|
||||
var a!: number;
|
||||
var b = a;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
let x!: string | number;
|
||||
if (typeof x === "string") {
|
||||
let s: string = x;
|
||||
}
|
||||
else {
|
||||
let n: number = x;
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
let x!: number;
|
||||
const g = () => {
|
||||
x = 1;
|
||||
}
|
||||
g();
|
||||
let y = x;
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
|
||||
function f4() {
|
||||
let a!;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
let b! = 1;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
let c!: number = 1;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare let v1!: number;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
declare var v2!: number;
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
//// [definiteAssignmentAssertions.ts]
|
||||
// Suppress strict property initialization check
|
||||
|
||||
class C1 {
|
||||
a!: number;
|
||||
b: string; // Error
|
||||
}
|
||||
|
||||
// Suppress definite assignment check in constructor
|
||||
|
||||
class C2 {
|
||||
a!: number;
|
||||
constructor() {
|
||||
let x = this.a;
|
||||
}
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
|
||||
class C3 {
|
||||
a! = 1;
|
||||
b!: number = 1;
|
||||
static c!: number;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare class C4 {
|
||||
a!: number;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
|
||||
abstract class C5 {
|
||||
abstract a!: number;
|
||||
}
|
||||
|
||||
// Suppress definite assignment check for variable
|
||||
|
||||
function f1() {
|
||||
let x!: number;
|
||||
let y = x;
|
||||
var a!: number;
|
||||
var b = a;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
let x!: string | number;
|
||||
if (typeof x === "string") {
|
||||
let s: string = x;
|
||||
}
|
||||
else {
|
||||
let n: number = x;
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
let x!: number;
|
||||
const g = () => {
|
||||
x = 1;
|
||||
}
|
||||
g();
|
||||
let y = x;
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
|
||||
function f4() {
|
||||
let a!;
|
||||
let b! = 1;
|
||||
let c!: number = 1;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare let v1!: number;
|
||||
declare var v2!: number;
|
||||
|
||||
|
||||
//// [definiteAssignmentAssertions.js]
|
||||
"use strict";
|
||||
// Suppress strict property initialization check
|
||||
var C1 = /** @class */ (function () {
|
||||
function C1() {
|
||||
}
|
||||
return C1;
|
||||
}());
|
||||
// Suppress definite assignment check in constructor
|
||||
var C2 = /** @class */ (function () {
|
||||
function C2() {
|
||||
var x = this.a;
|
||||
}
|
||||
return C2;
|
||||
}());
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
var C3 = /** @class */ (function () {
|
||||
function C3() {
|
||||
this.a = 1;
|
||||
this.b = 1;
|
||||
}
|
||||
return C3;
|
||||
}());
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
var C5 = /** @class */ (function () {
|
||||
function C5() {
|
||||
}
|
||||
return C5;
|
||||
}());
|
||||
// Suppress definite assignment check for variable
|
||||
function f1() {
|
||||
var x;
|
||||
var y = x;
|
||||
var a;
|
||||
var b = a;
|
||||
}
|
||||
function f2() {
|
||||
var x;
|
||||
if (typeof x === "string") {
|
||||
var s = x;
|
||||
}
|
||||
else {
|
||||
var n = x;
|
||||
}
|
||||
}
|
||||
function f3() {
|
||||
var x;
|
||||
var g = function () {
|
||||
x = 1;
|
||||
};
|
||||
g();
|
||||
var y = x;
|
||||
}
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
function f4() {
|
||||
var a;
|
||||
var b = 1;
|
||||
var c = 1;
|
||||
}
|
||||
|
||||
|
||||
//// [definiteAssignmentAssertions.d.ts]
|
||||
declare class C1 {
|
||||
a: number;
|
||||
b: string;
|
||||
}
|
||||
declare class C2 {
|
||||
a: number;
|
||||
constructor();
|
||||
}
|
||||
declare class C3 {
|
||||
a: number;
|
||||
b: number;
|
||||
static c: number;
|
||||
}
|
||||
declare class C4 {
|
||||
a: number;
|
||||
}
|
||||
declare abstract class C5 {
|
||||
abstract a: number;
|
||||
}
|
||||
declare function f1(): void;
|
||||
declare function f2(): void;
|
||||
declare function f3(): void;
|
||||
declare function f4(): void;
|
||||
declare let v1: number;
|
||||
declare var v2: number;
|
||||
@@ -0,0 +1,146 @@
|
||||
=== tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts ===
|
||||
// Suppress strict property initialization check
|
||||
|
||||
class C1 {
|
||||
>C1 : Symbol(C1, Decl(definiteAssignmentAssertions.ts, 0, 0))
|
||||
|
||||
a!: number;
|
||||
>a : Symbol(C1.a, Decl(definiteAssignmentAssertions.ts, 2, 10))
|
||||
|
||||
b: string; // Error
|
||||
>b : Symbol(C1.b, Decl(definiteAssignmentAssertions.ts, 3, 15))
|
||||
}
|
||||
|
||||
// Suppress definite assignment check in constructor
|
||||
|
||||
class C2 {
|
||||
>C2 : Symbol(C2, Decl(definiteAssignmentAssertions.ts, 5, 1))
|
||||
|
||||
a!: number;
|
||||
>a : Symbol(C2.a, Decl(definiteAssignmentAssertions.ts, 9, 10))
|
||||
|
||||
constructor() {
|
||||
let x = this.a;
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 12, 11))
|
||||
>this.a : Symbol(C2.a, Decl(definiteAssignmentAssertions.ts, 9, 10))
|
||||
>this : Symbol(C2, Decl(definiteAssignmentAssertions.ts, 5, 1))
|
||||
>a : Symbol(C2.a, Decl(definiteAssignmentAssertions.ts, 9, 10))
|
||||
}
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
|
||||
class C3 {
|
||||
>C3 : Symbol(C3, Decl(definiteAssignmentAssertions.ts, 14, 1))
|
||||
|
||||
a! = 1;
|
||||
>a : Symbol(C3.a, Decl(definiteAssignmentAssertions.ts, 18, 10))
|
||||
|
||||
b!: number = 1;
|
||||
>b : Symbol(C3.b, Decl(definiteAssignmentAssertions.ts, 19, 11))
|
||||
|
||||
static c!: number;
|
||||
>c : Symbol(C3.c, Decl(definiteAssignmentAssertions.ts, 20, 19))
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare class C4 {
|
||||
>C4 : Symbol(C4, Decl(definiteAssignmentAssertions.ts, 22, 1))
|
||||
|
||||
a!: number;
|
||||
>a : Symbol(C4.a, Decl(definiteAssignmentAssertions.ts, 26, 18))
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
|
||||
abstract class C5 {
|
||||
>C5 : Symbol(C5, Decl(definiteAssignmentAssertions.ts, 28, 1))
|
||||
|
||||
abstract a!: number;
|
||||
>a : Symbol(C5.a, Decl(definiteAssignmentAssertions.ts, 32, 19))
|
||||
}
|
||||
|
||||
// Suppress definite assignment check for variable
|
||||
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(definiteAssignmentAssertions.ts, 34, 1))
|
||||
|
||||
let x!: number;
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 39, 7))
|
||||
|
||||
let y = x;
|
||||
>y : Symbol(y, Decl(definiteAssignmentAssertions.ts, 40, 7))
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 39, 7))
|
||||
|
||||
var a!: number;
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertions.ts, 41, 7))
|
||||
|
||||
var b = a;
|
||||
>b : Symbol(b, Decl(definiteAssignmentAssertions.ts, 42, 7))
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertions.ts, 41, 7))
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(definiteAssignmentAssertions.ts, 43, 1))
|
||||
|
||||
let x!: string | number;
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 46, 7))
|
||||
|
||||
if (typeof x === "string") {
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 46, 7))
|
||||
|
||||
let s: string = x;
|
||||
>s : Symbol(s, Decl(definiteAssignmentAssertions.ts, 48, 11))
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 46, 7))
|
||||
}
|
||||
else {
|
||||
let n: number = x;
|
||||
>n : Symbol(n, Decl(definiteAssignmentAssertions.ts, 51, 11))
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 46, 7))
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(definiteAssignmentAssertions.ts, 53, 1))
|
||||
|
||||
let x!: number;
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 56, 7))
|
||||
|
||||
const g = () => {
|
||||
>g : Symbol(g, Decl(definiteAssignmentAssertions.ts, 57, 9))
|
||||
|
||||
x = 1;
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 56, 7))
|
||||
}
|
||||
g();
|
||||
>g : Symbol(g, Decl(definiteAssignmentAssertions.ts, 57, 9))
|
||||
|
||||
let y = x;
|
||||
>y : Symbol(y, Decl(definiteAssignmentAssertions.ts, 61, 7))
|
||||
>x : Symbol(x, Decl(definiteAssignmentAssertions.ts, 56, 7))
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
|
||||
function f4() {
|
||||
>f4 : Symbol(f4, Decl(definiteAssignmentAssertions.ts, 62, 1))
|
||||
|
||||
let a!;
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertions.ts, 67, 7))
|
||||
|
||||
let b! = 1;
|
||||
>b : Symbol(b, Decl(definiteAssignmentAssertions.ts, 68, 7))
|
||||
|
||||
let c!: number = 1;
|
||||
>c : Symbol(c, Decl(definiteAssignmentAssertions.ts, 69, 7))
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare let v1!: number;
|
||||
>v1 : Symbol(v1, Decl(definiteAssignmentAssertions.ts, 74, 11))
|
||||
|
||||
declare var v2!: number;
|
||||
>v2 : Symbol(v2, Decl(definiteAssignmentAssertions.ts, 75, 11))
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
=== tests/cases/conformance/controlFlow/definiteAssignmentAssertions.ts ===
|
||||
// Suppress strict property initialization check
|
||||
|
||||
class C1 {
|
||||
>C1 : C1
|
||||
|
||||
a!: number;
|
||||
>a : number
|
||||
|
||||
b: string; // Error
|
||||
>b : string
|
||||
}
|
||||
|
||||
// Suppress definite assignment check in constructor
|
||||
|
||||
class C2 {
|
||||
>C2 : C2
|
||||
|
||||
a!: number;
|
||||
>a : number
|
||||
|
||||
constructor() {
|
||||
let x = this.a;
|
||||
>x : number
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
}
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
|
||||
class C3 {
|
||||
>C3 : C3
|
||||
|
||||
a! = 1;
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
b!: number = 1;
|
||||
>b : number
|
||||
>1 : 1
|
||||
|
||||
static c!: number;
|
||||
>c : number
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare class C4 {
|
||||
>C4 : C4
|
||||
|
||||
a!: number;
|
||||
>a : number
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
|
||||
abstract class C5 {
|
||||
>C5 : C5
|
||||
|
||||
abstract a!: number;
|
||||
>a : number
|
||||
}
|
||||
|
||||
// Suppress definite assignment check for variable
|
||||
|
||||
function f1() {
|
||||
>f1 : () => void
|
||||
|
||||
let x!: number;
|
||||
>x : number
|
||||
|
||||
let y = x;
|
||||
>y : number
|
||||
>x : number
|
||||
|
||||
var a!: number;
|
||||
>a : number
|
||||
|
||||
var b = a;
|
||||
>b : number
|
||||
>a : number
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
|
||||
let x!: string | number;
|
||||
>x : string | number
|
||||
|
||||
if (typeof x === "string") {
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | number
|
||||
>"string" : "string"
|
||||
|
||||
let s: string = x;
|
||||
>s : string
|
||||
>x : string
|
||||
}
|
||||
else {
|
||||
let n: number = x;
|
||||
>n : number
|
||||
>x : number
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
|
||||
let x!: number;
|
||||
>x : number
|
||||
|
||||
const g = () => {
|
||||
>g : () => void
|
||||
>() => { x = 1; } : () => void
|
||||
|
||||
x = 1;
|
||||
>x = 1 : 1
|
||||
>x : number
|
||||
>1 : 1
|
||||
}
|
||||
g();
|
||||
>g() : void
|
||||
>g : () => void
|
||||
|
||||
let y = x;
|
||||
>y : number
|
||||
>x : number
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
|
||||
function f4() {
|
||||
>f4 : () => void
|
||||
|
||||
let a!;
|
||||
>a : any
|
||||
|
||||
let b! = 1;
|
||||
>b : number
|
||||
>1 : 1
|
||||
|
||||
let c!: number = 1;
|
||||
>c : number
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare let v1!: number;
|
||||
>v1 : number
|
||||
|
||||
declare var v2!: number;
|
||||
>v2 : number
|
||||
|
||||
@@ -10,7 +10,7 @@ type Data<T> = {
|
||||
};
|
||||
|
||||
class Parent<M> {
|
||||
private data: Data<M>;
|
||||
constructor(private data: Data<M>) {}
|
||||
getData(): Data<M> {
|
||||
return this.data;
|
||||
}
|
||||
@@ -50,7 +50,8 @@ var __extends = (this && this.__extends) || (function () {
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Parent = /** @class */ (function () {
|
||||
function Parent() {
|
||||
function Parent(data) {
|
||||
this.data = data;
|
||||
}
|
||||
Parent.prototype.getData = function () {
|
||||
return this.data;
|
||||
|
||||
@@ -29,20 +29,20 @@ class Parent<M> {
|
||||
>Parent : Symbol(Parent, Decl(indexedAccessTypeConstraints.ts, 8, 2))
|
||||
>M : Symbol(M, Decl(indexedAccessTypeConstraints.ts, 10, 13))
|
||||
|
||||
private data: Data<M>;
|
||||
>data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 10, 17))
|
||||
constructor(private data: Data<M>) {}
|
||||
>data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 11, 16))
|
||||
>Data : Symbol(Data, Decl(indexedAccessTypeConstraints.ts, 4, 1))
|
||||
>M : Symbol(M, Decl(indexedAccessTypeConstraints.ts, 10, 13))
|
||||
|
||||
getData(): Data<M> {
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 26))
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 41))
|
||||
>Data : Symbol(Data, Decl(indexedAccessTypeConstraints.ts, 4, 1))
|
||||
>M : Symbol(M, Decl(indexedAccessTypeConstraints.ts, 10, 13))
|
||||
|
||||
return this.data;
|
||||
>this.data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 10, 17))
|
||||
>this.data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 11, 16))
|
||||
>this : Symbol(Parent, Decl(indexedAccessTypeConstraints.ts, 8, 2))
|
||||
>data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 10, 17))
|
||||
>data : Symbol(Parent.data, Decl(indexedAccessTypeConstraints.ts, 11, 16))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,9 @@ export class Foo<C> extends Parent<IData<C>> {
|
||||
|
||||
return this.getData().get('content');
|
||||
>this.getData().get : Symbol(get, Decl(indexedAccessTypeConstraints.ts, 6, 16))
|
||||
>this.getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 26))
|
||||
>this.getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 41))
|
||||
>this : Symbol(Foo, Decl(indexedAccessTypeConstraints.ts, 15, 1))
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 26))
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 41))
|
||||
>get : Symbol(get, Decl(indexedAccessTypeConstraints.ts, 6, 16))
|
||||
}
|
||||
}
|
||||
@@ -81,9 +81,9 @@ export class Bar<C, T extends IData<C>> extends Parent<T> {
|
||||
|
||||
return this.getData().get('content');
|
||||
>this.getData().get : Symbol(get, Decl(indexedAccessTypeConstraints.ts, 6, 16))
|
||||
>this.getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 26))
|
||||
>this.getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 41))
|
||||
>this : Symbol(Bar, Decl(indexedAccessTypeConstraints.ts, 21, 1))
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 26))
|
||||
>getData : Symbol(Parent.getData, Decl(indexedAccessTypeConstraints.ts, 11, 41))
|
||||
>get : Symbol(get, Decl(indexedAccessTypeConstraints.ts, 6, 16))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class Parent<M> {
|
||||
>Parent : Parent<M>
|
||||
>M : M
|
||||
|
||||
private data: Data<M>;
|
||||
constructor(private data: Data<M>) {}
|
||||
>data : { get: <K extends keyof M>(prop: K) => M[K]; }
|
||||
>Data : { get: <K extends keyof T>(prop: K) => T[K]; }
|
||||
>M : M
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/a.js(2,14): error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
|
||||
/a.js(12,11): error TS1005: '{' expected.
|
||||
|
||||
|
||||
==== /a.js (2 errors) ====
|
||||
==== /a.js (1 errors) ====
|
||||
// Bad: missing a type
|
||||
/** @typedef T */
|
||||
~
|
||||
@@ -17,7 +16,5 @@
|
||||
*/
|
||||
|
||||
/** @type Person */
|
||||
~~~~~~
|
||||
!!! error TS1005: '{' expected.
|
||||
const person = { name: "" };
|
||||
|
||||
@@ -14,8 +14,8 @@ const t = 0;
|
||||
|
||||
/** @type Person */
|
||||
const person = { name: "" };
|
||||
>person : { [x: string]: any; name: string; }
|
||||
>{ name: "" } : { [x: string]: any; name: string; }
|
||||
>person : { name: string; }
|
||||
>{ name: "" } : { name: string; }
|
||||
>name : string
|
||||
>"" : ""
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @type Function
|
||||
*/
|
||||
var isArray = Array.isArray;
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>isArray : Function
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
=== tests/cases/compiler/modularizeLibrary_Dom.iterable.ts ===
|
||||
for (const element of document.getElementsByTagName("a")) {
|
||||
>element : Symbol(element, Decl(modularizeLibrary_Dom.iterable.ts, 0, 10))
|
||||
>document.getElementsByTagName : Symbol(Document.getElementsByTagName, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>document.getElementsByTagName : Symbol(Document.getElementsByTagName, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>document : Symbol(document, Decl(lib.dom.d.ts, --, --))
|
||||
>getElementsByTagName : Symbol(Document.getElementsByTagName, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>getElementsByTagName : Symbol(Document.getElementsByTagName, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
element.href;
|
||||
>element.href : Symbol(HTMLAnchorElement.href, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
for (const element of document.getElementsByTagName("a")) {
|
||||
>element : HTMLAnchorElement
|
||||
>document.getElementsByTagName("a") : NodeListOf<HTMLAnchorElement>
|
||||
>document.getElementsByTagName : { <K extends "symbol" | "object" | "abbr" | "acronym" | "address" | "article" | "aside" | "b" | "bdo" | "big" | "center" | "circle" | "cite" | "clippath" | "code" | "dd" | "defs" | "desc" | "dfn" | "dt" | "ellipse" | "em" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "figcaption" | "figure" | "filter" | "footer" | "foreignobject" | "g" | "header" | "hgroup" | "i" | "image" | "kbd" | "keygen" | "line" | "lineargradient" | "mark" | "marker" | "mask" | "metadata" | "nav" | "nobr" | "noframes" | "noscript" | "path" | "pattern" | "plaintext" | "polygon" | "polyline" | "radialgradient" | "rect" | "rt" | "ruby" | "s" | "samp" | "section" | "small" | "stop" | "strike" | "strong" | "sub" | "sup" | "svg" | "switch" | "text" | "textpath" | "tspan" | "tt" | "u" | "use" | "var" | "view" | "wbr" | "a" | "applet" | "area" | "audio" | "base" | "basefont" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "col" | "colgroup" | "data" | "datalist" | "del" | "dir" | "div" | "dl" | "embed" | "fieldset" | "font" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "hr" | "html" | "iframe" | "img" | "input" | "ins" | "isindex" | "label" | "legend" | "li" | "link" | "listing" | "map" | "marquee" | "menu" | "meta" | "meter" | "nextid" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "pre" | "progress" | "q" | "script" | "select" | "source" | "span" | "style" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "ul" | "video" | "x-ms-webview" | "xmp">(tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf<Element>; }
|
||||
>document.getElementsByTagName : { <K extends "object" | "a" | "abbr" | "acronym" | "address" | "applet" | "area" | "article" | "aside" | "audio" | "b" | "base" | "basefont" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "center" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "dfn" | "dir" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "font" | "footer" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "isindex" | "kbd" | "keygen" | "label" | "legend" | "li" | "link" | "listing" | "map" | "mark" | "marquee" | "menu" | "meta" | "meter" | "nav" | "nextid" | "nobr" | "noframes" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "plaintext" | "pre" | "progress" | "q" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "small" | "source" | "span" | "strike" | "strong" | "style" | "sub" | "sup" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "tt" | "u" | "ul" | "var" | "video" | "wbr" | "x-ms-webview" | "xmp">(tagname: K): NodeListOf<HTMLElementTagNameMap[K]>; <K extends "symbol" | "circle" | "clippath" | "defs" | "desc" | "ellipse" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "filter" | "foreignobject" | "g" | "image" | "line" | "lineargradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialgradient" | "rect" | "stop" | "svg" | "switch" | "text" | "textpath" | "tspan" | "use" | "view">(tagname: K): NodeListOf<SVGElementTagNameMap[K]>; (tagname: string): NodeListOf<Element>; }
|
||||
>document : Document
|
||||
>getElementsByTagName : { <K extends "symbol" | "object" | "abbr" | "acronym" | "address" | "article" | "aside" | "b" | "bdo" | "big" | "center" | "circle" | "cite" | "clippath" | "code" | "dd" | "defs" | "desc" | "dfn" | "dt" | "ellipse" | "em" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "figcaption" | "figure" | "filter" | "footer" | "foreignobject" | "g" | "header" | "hgroup" | "i" | "image" | "kbd" | "keygen" | "line" | "lineargradient" | "mark" | "marker" | "mask" | "metadata" | "nav" | "nobr" | "noframes" | "noscript" | "path" | "pattern" | "plaintext" | "polygon" | "polyline" | "radialgradient" | "rect" | "rt" | "ruby" | "s" | "samp" | "section" | "small" | "stop" | "strike" | "strong" | "sub" | "sup" | "svg" | "switch" | "text" | "textpath" | "tspan" | "tt" | "u" | "use" | "var" | "view" | "wbr" | "a" | "applet" | "area" | "audio" | "base" | "basefont" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "col" | "colgroup" | "data" | "datalist" | "del" | "dir" | "div" | "dl" | "embed" | "fieldset" | "font" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "hr" | "html" | "iframe" | "img" | "input" | "ins" | "isindex" | "label" | "legend" | "li" | "link" | "listing" | "map" | "marquee" | "menu" | "meta" | "meter" | "nextid" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "pre" | "progress" | "q" | "script" | "select" | "source" | "span" | "style" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "ul" | "video" | "x-ms-webview" | "xmp">(tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf<Element>; }
|
||||
>getElementsByTagName : { <K extends "object" | "a" | "abbr" | "acronym" | "address" | "applet" | "area" | "article" | "aside" | "audio" | "b" | "base" | "basefont" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "center" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "dfn" | "dir" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "font" | "footer" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "isindex" | "kbd" | "keygen" | "label" | "legend" | "li" | "link" | "listing" | "map" | "mark" | "marquee" | "menu" | "meta" | "meter" | "nav" | "nextid" | "nobr" | "noframes" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "plaintext" | "pre" | "progress" | "q" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "small" | "source" | "span" | "strike" | "strong" | "style" | "sub" | "sup" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "tt" | "u" | "ul" | "var" | "video" | "wbr" | "x-ms-webview" | "xmp">(tagname: K): NodeListOf<HTMLElementTagNameMap[K]>; <K extends "symbol" | "circle" | "clippath" | "defs" | "desc" | "ellipse" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "filter" | "foreignobject" | "g" | "image" | "line" | "lineargradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialgradient" | "rect" | "stop" | "svg" | "switch" | "text" | "textpath" | "tspan" | "use" | "view">(tagname: K): NodeListOf<SVGElementTagNameMap[K]>; (tagname: string): NodeListOf<Element>; }
|
||||
>"a" : "a"
|
||||
|
||||
element.href;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//// [narrowingConstrainedTypeVariable.ts]
|
||||
// Repro from #20138
|
||||
|
||||
class C { }
|
||||
|
||||
function f1<T extends C>(v: T | string): void {
|
||||
if (v instanceof C) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const s: string = v;
|
||||
}
|
||||
}
|
||||
|
||||
class D { }
|
||||
|
||||
function f2<T extends C, U extends D>(v: T | U) {
|
||||
if (v instanceof C) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const y: U = v;
|
||||
}
|
||||
}
|
||||
|
||||
class E { x: string | undefined }
|
||||
|
||||
function f3<T extends E>(v: T | { x: string }) {
|
||||
if (v instanceof E) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const y: { x: string } = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [narrowingConstrainedTypeVariable.js]
|
||||
"use strict";
|
||||
// Repro from #20138
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
function f1(v) {
|
||||
if (v instanceof C) {
|
||||
var x = v;
|
||||
}
|
||||
else {
|
||||
var s = v;
|
||||
}
|
||||
}
|
||||
var D = /** @class */ (function () {
|
||||
function D() {
|
||||
}
|
||||
return D;
|
||||
}());
|
||||
function f2(v) {
|
||||
if (v instanceof C) {
|
||||
var x = v;
|
||||
}
|
||||
else {
|
||||
var y = v;
|
||||
}
|
||||
}
|
||||
var E = /** @class */ (function () {
|
||||
function E() {
|
||||
}
|
||||
return E;
|
||||
}());
|
||||
function f3(v) {
|
||||
if (v instanceof E) {
|
||||
var x = v;
|
||||
}
|
||||
else {
|
||||
var y = v;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/instanceOf/narrowingConstrainedTypeVariable.ts ===
|
||||
// Repro from #20138
|
||||
|
||||
class C { }
|
||||
>C : Symbol(C, Decl(narrowingConstrainedTypeVariable.ts, 0, 0))
|
||||
|
||||
function f1<T extends C>(v: T | string): void {
|
||||
>f1 : Symbol(f1, Decl(narrowingConstrainedTypeVariable.ts, 2, 11))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 4, 12))
|
||||
>C : Symbol(C, Decl(narrowingConstrainedTypeVariable.ts, 0, 0))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 4, 25))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 4, 12))
|
||||
|
||||
if (v instanceof C) {
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 4, 25))
|
||||
>C : Symbol(C, Decl(narrowingConstrainedTypeVariable.ts, 0, 0))
|
||||
|
||||
const x: T = v;
|
||||
>x : Symbol(x, Decl(narrowingConstrainedTypeVariable.ts, 6, 13))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 4, 12))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 4, 25))
|
||||
}
|
||||
else {
|
||||
const s: string = v;
|
||||
>s : Symbol(s, Decl(narrowingConstrainedTypeVariable.ts, 9, 13))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 4, 25))
|
||||
}
|
||||
}
|
||||
|
||||
class D { }
|
||||
>D : Symbol(D, Decl(narrowingConstrainedTypeVariable.ts, 11, 1))
|
||||
|
||||
function f2<T extends C, U extends D>(v: T | U) {
|
||||
>f2 : Symbol(f2, Decl(narrowingConstrainedTypeVariable.ts, 13, 11))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 15, 12))
|
||||
>C : Symbol(C, Decl(narrowingConstrainedTypeVariable.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(narrowingConstrainedTypeVariable.ts, 15, 24))
|
||||
>D : Symbol(D, Decl(narrowingConstrainedTypeVariable.ts, 11, 1))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 15, 38))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 15, 12))
|
||||
>U : Symbol(U, Decl(narrowingConstrainedTypeVariable.ts, 15, 24))
|
||||
|
||||
if (v instanceof C) {
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 15, 38))
|
||||
>C : Symbol(C, Decl(narrowingConstrainedTypeVariable.ts, 0, 0))
|
||||
|
||||
const x: T = v;
|
||||
>x : Symbol(x, Decl(narrowingConstrainedTypeVariable.ts, 17, 13))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 15, 12))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 15, 38))
|
||||
}
|
||||
else {
|
||||
const y: U = v;
|
||||
>y : Symbol(y, Decl(narrowingConstrainedTypeVariable.ts, 20, 13))
|
||||
>U : Symbol(U, Decl(narrowingConstrainedTypeVariable.ts, 15, 24))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 15, 38))
|
||||
}
|
||||
}
|
||||
|
||||
class E { x: string | undefined }
|
||||
>E : Symbol(E, Decl(narrowingConstrainedTypeVariable.ts, 22, 1))
|
||||
>x : Symbol(E.x, Decl(narrowingConstrainedTypeVariable.ts, 24, 9))
|
||||
|
||||
function f3<T extends E>(v: T | { x: string }) {
|
||||
>f3 : Symbol(f3, Decl(narrowingConstrainedTypeVariable.ts, 24, 33))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 26, 12))
|
||||
>E : Symbol(E, Decl(narrowingConstrainedTypeVariable.ts, 22, 1))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 26, 25))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 26, 12))
|
||||
>x : Symbol(x, Decl(narrowingConstrainedTypeVariable.ts, 26, 33))
|
||||
|
||||
if (v instanceof E) {
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 26, 25))
|
||||
>E : Symbol(E, Decl(narrowingConstrainedTypeVariable.ts, 22, 1))
|
||||
|
||||
const x: T = v;
|
||||
>x : Symbol(x, Decl(narrowingConstrainedTypeVariable.ts, 28, 13))
|
||||
>T : Symbol(T, Decl(narrowingConstrainedTypeVariable.ts, 26, 12))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 26, 25))
|
||||
}
|
||||
else {
|
||||
const y: { x: string } = v;
|
||||
>y : Symbol(y, Decl(narrowingConstrainedTypeVariable.ts, 31, 13))
|
||||
>x : Symbol(x, Decl(narrowingConstrainedTypeVariable.ts, 31, 18))
|
||||
>v : Symbol(v, Decl(narrowingConstrainedTypeVariable.ts, 26, 25))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/instanceOf/narrowingConstrainedTypeVariable.ts ===
|
||||
// Repro from #20138
|
||||
|
||||
class C { }
|
||||
>C : C
|
||||
|
||||
function f1<T extends C>(v: T | string): void {
|
||||
>f1 : <T extends C>(v: string | T) => void
|
||||
>T : T
|
||||
>C : C
|
||||
>v : string | T
|
||||
>T : T
|
||||
|
||||
if (v instanceof C) {
|
||||
>v instanceof C : boolean
|
||||
>v : string | T
|
||||
>C : typeof C
|
||||
|
||||
const x: T = v;
|
||||
>x : T
|
||||
>T : T
|
||||
>v : T
|
||||
}
|
||||
else {
|
||||
const s: string = v;
|
||||
>s : string
|
||||
>v : string
|
||||
}
|
||||
}
|
||||
|
||||
class D { }
|
||||
>D : D
|
||||
|
||||
function f2<T extends C, U extends D>(v: T | U) {
|
||||
>f2 : <T extends C, U extends D>(v: T | U) => void
|
||||
>T : T
|
||||
>C : C
|
||||
>U : U
|
||||
>D : D
|
||||
>v : T | U
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
if (v instanceof C) {
|
||||
>v instanceof C : boolean
|
||||
>v : T | U
|
||||
>C : typeof C
|
||||
|
||||
const x: T = v;
|
||||
>x : T
|
||||
>T : T
|
||||
>v : T
|
||||
}
|
||||
else {
|
||||
const y: U = v;
|
||||
>y : U
|
||||
>U : U
|
||||
>v : U
|
||||
}
|
||||
}
|
||||
|
||||
class E { x: string | undefined }
|
||||
>E : E
|
||||
>x : string | undefined
|
||||
|
||||
function f3<T extends E>(v: T | { x: string }) {
|
||||
>f3 : <T extends E>(v: T | { x: string; }) => void
|
||||
>T : T
|
||||
>E : E
|
||||
>v : T | { x: string; }
|
||||
>T : T
|
||||
>x : string
|
||||
|
||||
if (v instanceof E) {
|
||||
>v instanceof E : boolean
|
||||
>v : T | { x: string; }
|
||||
>E : typeof E
|
||||
|
||||
const x: T = v;
|
||||
>x : T
|
||||
>T : T
|
||||
>v : T
|
||||
}
|
||||
else {
|
||||
const y: { x: string } = v;
|
||||
>y : { x: string; }
|
||||
>x : string
|
||||
>v : { x: string; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(4,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(6,5): error TS2564: Property 'c' has no initializer and is not definitely assigned in the constructor.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(48,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(71,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(93,22): error TS2565: Property 'a' is used before being assigned.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts(94,23): error TS2565: Property 'b' is used before being assigned.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts (6 errors) ====
|
||||
// Properties with non-undefined types require initialization
|
||||
|
||||
class C1 {
|
||||
a: number; // Error
|
||||
~
|
||||
!!! error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
b: number | undefined;
|
||||
c: number | null; // Error
|
||||
~
|
||||
!!! error TS2564: Property 'c' has no initializer and is not definitely assigned in the constructor.
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks in ambient contexts
|
||||
|
||||
declare class C2 {
|
||||
a: number;
|
||||
b: number | undefined;
|
||||
c: number | null;
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for static members
|
||||
|
||||
class C3 {
|
||||
static a: number;
|
||||
static b: number | undefined;
|
||||
static c: number | null;
|
||||
static d?: number;
|
||||
}
|
||||
|
||||
// Initializer satisfies strict initialization check
|
||||
|
||||
class C4 {
|
||||
a = 0;
|
||||
b: number = 0;
|
||||
c: string = "abc";
|
||||
}
|
||||
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
|
||||
class C5 {
|
||||
a: number;
|
||||
constructor() {
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// All code paths must contain assignment
|
||||
|
||||
class C6 {
|
||||
a: number; // Error
|
||||
~
|
||||
!!! error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class C7 {
|
||||
a: number;
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
this.a = 1;
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Properties with string literal names aren't checked
|
||||
|
||||
class C8 {
|
||||
a: number; // Error
|
||||
~
|
||||
!!! error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for abstract members
|
||||
|
||||
abstract class C9 {
|
||||
abstract a: number;
|
||||
abstract b: number | undefined;
|
||||
abstract c: number | null;
|
||||
abstract d?: number;
|
||||
}
|
||||
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
|
||||
class C10 {
|
||||
a: number;
|
||||
b: number;
|
||||
c?: number;
|
||||
constructor() {
|
||||
let x = this.a; // Error
|
||||
~
|
||||
!!! error TS2565: Property 'a' is used before being assigned.
|
||||
this.a = this.b; // Error
|
||||
~
|
||||
!!! error TS2565: Property 'b' is used before being assigned.
|
||||
this.b = x;
|
||||
let y = this.c;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
//// [strictPropertyInitialization.ts]
|
||||
// Properties with non-undefined types require initialization
|
||||
|
||||
class C1 {
|
||||
a: number; // Error
|
||||
b: number | undefined;
|
||||
c: number | null; // Error
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks in ambient contexts
|
||||
|
||||
declare class C2 {
|
||||
a: number;
|
||||
b: number | undefined;
|
||||
c: number | null;
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for static members
|
||||
|
||||
class C3 {
|
||||
static a: number;
|
||||
static b: number | undefined;
|
||||
static c: number | null;
|
||||
static d?: number;
|
||||
}
|
||||
|
||||
// Initializer satisfies strict initialization check
|
||||
|
||||
class C4 {
|
||||
a = 0;
|
||||
b: number = 0;
|
||||
c: string = "abc";
|
||||
}
|
||||
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
|
||||
class C5 {
|
||||
a: number;
|
||||
constructor() {
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// All code paths must contain assignment
|
||||
|
||||
class C6 {
|
||||
a: number; // Error
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class C7 {
|
||||
a: number;
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
this.a = 1;
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Properties with string literal names aren't checked
|
||||
|
||||
class C8 {
|
||||
a: number; // Error
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for abstract members
|
||||
|
||||
abstract class C9 {
|
||||
abstract a: number;
|
||||
abstract b: number | undefined;
|
||||
abstract c: number | null;
|
||||
abstract d?: number;
|
||||
}
|
||||
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
|
||||
class C10 {
|
||||
a: number;
|
||||
b: number;
|
||||
c?: number;
|
||||
constructor() {
|
||||
let x = this.a; // Error
|
||||
this.a = this.b; // Error
|
||||
this.b = x;
|
||||
let y = this.c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [strictPropertyInitialization.js]
|
||||
"use strict";
|
||||
// Properties with non-undefined types require initialization
|
||||
var C1 = /** @class */ (function () {
|
||||
function C1() {
|
||||
}
|
||||
return C1;
|
||||
}());
|
||||
// No strict initialization checks for static members
|
||||
var C3 = /** @class */ (function () {
|
||||
function C3() {
|
||||
}
|
||||
return C3;
|
||||
}());
|
||||
// Initializer satisfies strict initialization check
|
||||
var C4 = /** @class */ (function () {
|
||||
function C4() {
|
||||
this.a = 0;
|
||||
this.b = 0;
|
||||
this.c = "abc";
|
||||
}
|
||||
return C4;
|
||||
}());
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
var C5 = /** @class */ (function () {
|
||||
function C5() {
|
||||
this.a = 0;
|
||||
}
|
||||
return C5;
|
||||
}());
|
||||
// All code paths must contain assignment
|
||||
var C6 = /** @class */ (function () {
|
||||
function C6(cond) {
|
||||
if (cond) {
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
return C6;
|
||||
}());
|
||||
var C7 = /** @class */ (function () {
|
||||
function C7(cond) {
|
||||
if (cond) {
|
||||
this.a = 1;
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
return C7;
|
||||
}());
|
||||
// Properties with string literal names aren't checked
|
||||
var C8 = /** @class */ (function () {
|
||||
function C8() {
|
||||
}
|
||||
return C8;
|
||||
}());
|
||||
// No strict initialization checks for abstract members
|
||||
var C9 = /** @class */ (function () {
|
||||
function C9() {
|
||||
}
|
||||
return C9;
|
||||
}());
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
var C10 = /** @class */ (function () {
|
||||
function C10() {
|
||||
var x = this.a; // Error
|
||||
this.a = this.b; // Error
|
||||
this.b = x;
|
||||
var y = this.c;
|
||||
}
|
||||
return C10;
|
||||
}());
|
||||
|
||||
|
||||
//// [strictPropertyInitialization.d.ts]
|
||||
declare class C1 {
|
||||
a: number;
|
||||
b: number | undefined;
|
||||
c: number | null;
|
||||
d?: number;
|
||||
}
|
||||
declare class C2 {
|
||||
a: number;
|
||||
b: number | undefined;
|
||||
c: number | null;
|
||||
d?: number;
|
||||
}
|
||||
declare class C3 {
|
||||
static a: number;
|
||||
static b: number | undefined;
|
||||
static c: number | null;
|
||||
static d?: number;
|
||||
}
|
||||
declare class C4 {
|
||||
a: number;
|
||||
b: number;
|
||||
c: string;
|
||||
}
|
||||
declare class C5 {
|
||||
a: number;
|
||||
constructor();
|
||||
}
|
||||
declare class C6 {
|
||||
a: number;
|
||||
constructor(cond: boolean);
|
||||
}
|
||||
declare class C7 {
|
||||
a: number;
|
||||
constructor(cond: boolean);
|
||||
}
|
||||
declare class C8 {
|
||||
a: number;
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
declare abstract class C9 {
|
||||
abstract a: number;
|
||||
abstract b: number | undefined;
|
||||
abstract c: number | null;
|
||||
abstract d?: number;
|
||||
}
|
||||
declare class C10 {
|
||||
a: number;
|
||||
b: number;
|
||||
c?: number;
|
||||
constructor();
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts ===
|
||||
// Properties with non-undefined types require initialization
|
||||
|
||||
class C1 {
|
||||
>C1 : Symbol(C1, Decl(strictPropertyInitialization.ts, 0, 0))
|
||||
|
||||
a: number; // Error
|
||||
>a : Symbol(C1.a, Decl(strictPropertyInitialization.ts, 2, 10))
|
||||
|
||||
b: number | undefined;
|
||||
>b : Symbol(C1.b, Decl(strictPropertyInitialization.ts, 3, 14))
|
||||
|
||||
c: number | null; // Error
|
||||
>c : Symbol(C1.c, Decl(strictPropertyInitialization.ts, 4, 26))
|
||||
|
||||
d?: number;
|
||||
>d : Symbol(C1.d, Decl(strictPropertyInitialization.ts, 5, 21))
|
||||
}
|
||||
|
||||
// No strict initialization checks in ambient contexts
|
||||
|
||||
declare class C2 {
|
||||
>C2 : Symbol(C2, Decl(strictPropertyInitialization.ts, 7, 1))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(C2.a, Decl(strictPropertyInitialization.ts, 11, 18))
|
||||
|
||||
b: number | undefined;
|
||||
>b : Symbol(C2.b, Decl(strictPropertyInitialization.ts, 12, 14))
|
||||
|
||||
c: number | null;
|
||||
>c : Symbol(C2.c, Decl(strictPropertyInitialization.ts, 13, 26))
|
||||
|
||||
d?: number;
|
||||
>d : Symbol(C2.d, Decl(strictPropertyInitialization.ts, 14, 21))
|
||||
}
|
||||
|
||||
// No strict initialization checks for static members
|
||||
|
||||
class C3 {
|
||||
>C3 : Symbol(C3, Decl(strictPropertyInitialization.ts, 16, 1))
|
||||
|
||||
static a: number;
|
||||
>a : Symbol(C3.a, Decl(strictPropertyInitialization.ts, 20, 10))
|
||||
|
||||
static b: number | undefined;
|
||||
>b : Symbol(C3.b, Decl(strictPropertyInitialization.ts, 21, 21))
|
||||
|
||||
static c: number | null;
|
||||
>c : Symbol(C3.c, Decl(strictPropertyInitialization.ts, 22, 33))
|
||||
|
||||
static d?: number;
|
||||
>d : Symbol(C3.d, Decl(strictPropertyInitialization.ts, 23, 28))
|
||||
}
|
||||
|
||||
// Initializer satisfies strict initialization check
|
||||
|
||||
class C4 {
|
||||
>C4 : Symbol(C4, Decl(strictPropertyInitialization.ts, 25, 1))
|
||||
|
||||
a = 0;
|
||||
>a : Symbol(C4.a, Decl(strictPropertyInitialization.ts, 29, 10))
|
||||
|
||||
b: number = 0;
|
||||
>b : Symbol(C4.b, Decl(strictPropertyInitialization.ts, 30, 10))
|
||||
|
||||
c: string = "abc";
|
||||
>c : Symbol(C4.c, Decl(strictPropertyInitialization.ts, 31, 18))
|
||||
}
|
||||
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
|
||||
class C5 {
|
||||
>C5 : Symbol(C5, Decl(strictPropertyInitialization.ts, 33, 1))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(C5.a, Decl(strictPropertyInitialization.ts, 37, 10))
|
||||
|
||||
constructor() {
|
||||
this.a = 0;
|
||||
>this.a : Symbol(C5.a, Decl(strictPropertyInitialization.ts, 37, 10))
|
||||
>this : Symbol(C5, Decl(strictPropertyInitialization.ts, 33, 1))
|
||||
>a : Symbol(C5.a, Decl(strictPropertyInitialization.ts, 37, 10))
|
||||
}
|
||||
}
|
||||
|
||||
// All code paths must contain assignment
|
||||
|
||||
class C6 {
|
||||
>C6 : Symbol(C6, Decl(strictPropertyInitialization.ts, 42, 1))
|
||||
|
||||
a: number; // Error
|
||||
>a : Symbol(C6.a, Decl(strictPropertyInitialization.ts, 46, 10))
|
||||
|
||||
constructor(cond: boolean) {
|
||||
>cond : Symbol(cond, Decl(strictPropertyInitialization.ts, 48, 16))
|
||||
|
||||
if (cond) {
|
||||
>cond : Symbol(cond, Decl(strictPropertyInitialization.ts, 48, 16))
|
||||
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
>this.a : Symbol(C6.a, Decl(strictPropertyInitialization.ts, 46, 10))
|
||||
>this : Symbol(C6, Decl(strictPropertyInitialization.ts, 42, 1))
|
||||
>a : Symbol(C6.a, Decl(strictPropertyInitialization.ts, 46, 10))
|
||||
}
|
||||
}
|
||||
|
||||
class C7 {
|
||||
>C7 : Symbol(C7, Decl(strictPropertyInitialization.ts, 54, 1))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(C7.a, Decl(strictPropertyInitialization.ts, 56, 10))
|
||||
|
||||
constructor(cond: boolean) {
|
||||
>cond : Symbol(cond, Decl(strictPropertyInitialization.ts, 58, 16))
|
||||
|
||||
if (cond) {
|
||||
>cond : Symbol(cond, Decl(strictPropertyInitialization.ts, 58, 16))
|
||||
|
||||
this.a = 1;
|
||||
>this.a : Symbol(C7.a, Decl(strictPropertyInitialization.ts, 56, 10))
|
||||
>this : Symbol(C7, Decl(strictPropertyInitialization.ts, 54, 1))
|
||||
>a : Symbol(C7.a, Decl(strictPropertyInitialization.ts, 56, 10))
|
||||
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
>this.a : Symbol(C7.a, Decl(strictPropertyInitialization.ts, 56, 10))
|
||||
>this : Symbol(C7, Decl(strictPropertyInitialization.ts, 54, 1))
|
||||
>a : Symbol(C7.a, Decl(strictPropertyInitialization.ts, 56, 10))
|
||||
}
|
||||
}
|
||||
|
||||
// Properties with string literal names aren't checked
|
||||
|
||||
class C8 {
|
||||
>C8 : Symbol(C8, Decl(strictPropertyInitialization.ts, 65, 1))
|
||||
|
||||
a: number; // Error
|
||||
>a : Symbol(C8.a, Decl(strictPropertyInitialization.ts, 69, 10))
|
||||
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for abstract members
|
||||
|
||||
abstract class C9 {
|
||||
>C9 : Symbol(C9, Decl(strictPropertyInitialization.ts, 73, 1))
|
||||
|
||||
abstract a: number;
|
||||
>a : Symbol(C9.a, Decl(strictPropertyInitialization.ts, 77, 19))
|
||||
|
||||
abstract b: number | undefined;
|
||||
>b : Symbol(C9.b, Decl(strictPropertyInitialization.ts, 78, 23))
|
||||
|
||||
abstract c: number | null;
|
||||
>c : Symbol(C9.c, Decl(strictPropertyInitialization.ts, 79, 35))
|
||||
|
||||
abstract d?: number;
|
||||
>d : Symbol(C9.d, Decl(strictPropertyInitialization.ts, 80, 30))
|
||||
}
|
||||
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
|
||||
class C10 {
|
||||
>C10 : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(C10.a, Decl(strictPropertyInitialization.ts, 87, 11))
|
||||
|
||||
b: number;
|
||||
>b : Symbol(C10.b, Decl(strictPropertyInitialization.ts, 88, 14))
|
||||
|
||||
c?: number;
|
||||
>c : Symbol(C10.c, Decl(strictPropertyInitialization.ts, 89, 14))
|
||||
|
||||
constructor() {
|
||||
let x = this.a; // Error
|
||||
>x : Symbol(x, Decl(strictPropertyInitialization.ts, 92, 11))
|
||||
>this.a : Symbol(C10.a, Decl(strictPropertyInitialization.ts, 87, 11))
|
||||
>this : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
>a : Symbol(C10.a, Decl(strictPropertyInitialization.ts, 87, 11))
|
||||
|
||||
this.a = this.b; // Error
|
||||
>this.a : Symbol(C10.a, Decl(strictPropertyInitialization.ts, 87, 11))
|
||||
>this : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
>a : Symbol(C10.a, Decl(strictPropertyInitialization.ts, 87, 11))
|
||||
>this.b : Symbol(C10.b, Decl(strictPropertyInitialization.ts, 88, 14))
|
||||
>this : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
>b : Symbol(C10.b, Decl(strictPropertyInitialization.ts, 88, 14))
|
||||
|
||||
this.b = x;
|
||||
>this.b : Symbol(C10.b, Decl(strictPropertyInitialization.ts, 88, 14))
|
||||
>this : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
>b : Symbol(C10.b, Decl(strictPropertyInitialization.ts, 88, 14))
|
||||
>x : Symbol(x, Decl(strictPropertyInitialization.ts, 92, 11))
|
||||
|
||||
let y = this.c;
|
||||
>y : Symbol(y, Decl(strictPropertyInitialization.ts, 95, 11))
|
||||
>this.c : Symbol(C10.c, Decl(strictPropertyInitialization.ts, 89, 14))
|
||||
>this : Symbol(C10, Decl(strictPropertyInitialization.ts, 82, 1))
|
||||
>c : Symbol(C10.c, Decl(strictPropertyInitialization.ts, 89, 14))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts ===
|
||||
// Properties with non-undefined types require initialization
|
||||
|
||||
class C1 {
|
||||
>C1 : C1
|
||||
|
||||
a: number; // Error
|
||||
>a : number
|
||||
|
||||
b: number | undefined;
|
||||
>b : number | undefined
|
||||
|
||||
c: number | null; // Error
|
||||
>c : number | null
|
||||
>null : null
|
||||
|
||||
d?: number;
|
||||
>d : number | undefined
|
||||
}
|
||||
|
||||
// No strict initialization checks in ambient contexts
|
||||
|
||||
declare class C2 {
|
||||
>C2 : C2
|
||||
|
||||
a: number;
|
||||
>a : number
|
||||
|
||||
b: number | undefined;
|
||||
>b : number | undefined
|
||||
|
||||
c: number | null;
|
||||
>c : number | null
|
||||
>null : null
|
||||
|
||||
d?: number;
|
||||
>d : number | undefined
|
||||
}
|
||||
|
||||
// No strict initialization checks for static members
|
||||
|
||||
class C3 {
|
||||
>C3 : C3
|
||||
|
||||
static a: number;
|
||||
>a : number
|
||||
|
||||
static b: number | undefined;
|
||||
>b : number | undefined
|
||||
|
||||
static c: number | null;
|
||||
>c : number | null
|
||||
>null : null
|
||||
|
||||
static d?: number;
|
||||
>d : number | undefined
|
||||
}
|
||||
|
||||
// Initializer satisfies strict initialization check
|
||||
|
||||
class C4 {
|
||||
>C4 : C4
|
||||
|
||||
a = 0;
|
||||
>a : number
|
||||
>0 : 0
|
||||
|
||||
b: number = 0;
|
||||
>b : number
|
||||
>0 : 0
|
||||
|
||||
c: string = "abc";
|
||||
>c : string
|
||||
>"abc" : "abc"
|
||||
}
|
||||
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
|
||||
class C5 {
|
||||
>C5 : C5
|
||||
|
||||
a: number;
|
||||
>a : number
|
||||
|
||||
constructor() {
|
||||
this.a = 0;
|
||||
>this.a = 0 : 0
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
// All code paths must contain assignment
|
||||
|
||||
class C6 {
|
||||
>C6 : C6
|
||||
|
||||
a: number; // Error
|
||||
>a : number
|
||||
|
||||
constructor(cond: boolean) {
|
||||
>cond : boolean
|
||||
|
||||
if (cond) {
|
||||
>cond : boolean
|
||||
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
>this.a = 0 : 0
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
class C7 {
|
||||
>C7 : C7
|
||||
|
||||
a: number;
|
||||
>a : number
|
||||
|
||||
constructor(cond: boolean) {
|
||||
>cond : boolean
|
||||
|
||||
if (cond) {
|
||||
>cond : boolean
|
||||
|
||||
this.a = 1;
|
||||
>this.a = 1 : 1
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
>this.a = 0 : 0
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
// Properties with string literal names aren't checked
|
||||
|
||||
class C8 {
|
||||
>C8 : C8
|
||||
|
||||
a: number; // Error
|
||||
>a : number
|
||||
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for abstract members
|
||||
|
||||
abstract class C9 {
|
||||
>C9 : C9
|
||||
|
||||
abstract a: number;
|
||||
>a : number
|
||||
|
||||
abstract b: number | undefined;
|
||||
>b : number | undefined
|
||||
|
||||
abstract c: number | null;
|
||||
>c : number | null
|
||||
>null : null
|
||||
|
||||
abstract d?: number;
|
||||
>d : number | undefined
|
||||
}
|
||||
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
|
||||
class C10 {
|
||||
>C10 : C10
|
||||
|
||||
a: number;
|
||||
>a : number
|
||||
|
||||
b: number;
|
||||
>b : number
|
||||
|
||||
c?: number;
|
||||
>c : number | undefined
|
||||
|
||||
constructor() {
|
||||
let x = this.a; // Error
|
||||
>x : number
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
|
||||
this.a = this.b; // Error
|
||||
>this.a = this.b : number
|
||||
>this.a : number
|
||||
>this : this
|
||||
>a : number
|
||||
>this.b : number
|
||||
>this : this
|
||||
>b : number
|
||||
|
||||
this.b = x;
|
||||
>this.b = x : number
|
||||
>this.b : number
|
||||
>this : this
|
||||
>b : number
|
||||
>x : number
|
||||
|
||||
let y = this.c;
|
||||
>y : number | undefined
|
||||
>this.c : number | undefined
|
||||
>this : this
|
||||
>c : number | undefined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ tests/cases/conformance/jsdoc/badTypeArguments.js(2,22): error TS1009: Trailing
|
||||
/** @param {C.<number,>} y */
|
||||
~
|
||||
!!! error TS1009: Trailing comma not allowed.
|
||||
function f(x, y) {
|
||||
// @ts-ignore
|
||||
/** @param {C.<number,>} skipped */
|
||||
function f(x, y, skipped) {
|
||||
return x.t + y.t;
|
||||
}
|
||||
var x = f({ t: 1000 }, { t: 3000 });
|
||||
var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 });
|
||||
|
||||
@@ -8,22 +8,26 @@ declare class C<T> { t: T }
|
||||
=== tests/cases/conformance/jsdoc/badTypeArguments.js ===
|
||||
/** @param {C.<>} x */
|
||||
/** @param {C.<number,>} y */
|
||||
function f(x, y) {
|
||||
// @ts-ignore
|
||||
/** @param {C.<number,>} skipped */
|
||||
function f(x, y, skipped) {
|
||||
>f : Symbol(f, Decl(badTypeArguments.js, 0, 0))
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 2, 11))
|
||||
>y : Symbol(y, Decl(badTypeArguments.js, 2, 13))
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 4, 11))
|
||||
>y : Symbol(y, Decl(badTypeArguments.js, 4, 13))
|
||||
>skipped : Symbol(skipped, Decl(badTypeArguments.js, 4, 16))
|
||||
|
||||
return x.t + y.t;
|
||||
>x.t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20))
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 2, 11))
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 4, 11))
|
||||
>t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20))
|
||||
>y.t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20))
|
||||
>y : Symbol(y, Decl(badTypeArguments.js, 2, 13))
|
||||
>y : Symbol(y, Decl(badTypeArguments.js, 4, 13))
|
||||
>t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20))
|
||||
}
|
||||
var x = f({ t: 1000 }, { t: 3000 });
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 5, 3))
|
||||
var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 });
|
||||
>x : Symbol(x, Decl(badTypeArguments.js, 7, 3))
|
||||
>f : Symbol(f, Decl(badTypeArguments.js, 0, 0))
|
||||
>t : Symbol(t, Decl(badTypeArguments.js, 5, 11))
|
||||
>t : Symbol(t, Decl(badTypeArguments.js, 5, 24))
|
||||
>t : Symbol(t, Decl(badTypeArguments.js, 7, 11))
|
||||
>t : Symbol(t, Decl(badTypeArguments.js, 7, 24))
|
||||
>t : Symbol(t, Decl(badTypeArguments.js, 7, 37))
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@ declare class C<T> { t: T }
|
||||
=== tests/cases/conformance/jsdoc/badTypeArguments.js ===
|
||||
/** @param {C.<>} x */
|
||||
/** @param {C.<number,>} y */
|
||||
function f(x, y) {
|
||||
>f : (x: C<any>, y: C<number>) => any
|
||||
// @ts-ignore
|
||||
/** @param {C.<number,>} skipped */
|
||||
function f(x, y, skipped) {
|
||||
>f : (x: C<any>, y: C<number>, skipped: C<number>) => any
|
||||
>x : C<any>
|
||||
>y : C<number>
|
||||
>skipped : C<number>
|
||||
|
||||
return x.t + y.t;
|
||||
>x.t + y.t : any
|
||||
@@ -22,14 +25,17 @@ function f(x, y) {
|
||||
>y : C<number>
|
||||
>t : number
|
||||
}
|
||||
var x = f({ t: 1000 }, { t: 3000 });
|
||||
var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 });
|
||||
>x : any
|
||||
>f({ t: 1000 }, { t: 3000 }) : any
|
||||
>f : (x: C<any>, y: C<number>) => any
|
||||
>f({ t: 1000 }, { t: 3000 }, { t: 5000 }) : any
|
||||
>f : (x: C<any>, y: C<number>, skipped: C<number>) => any
|
||||
>{ t: 1000 } : { t: number; }
|
||||
>t : number
|
||||
>1000 : 1000
|
||||
>{ t: 3000 } : { t: number; }
|
||||
>t : number
|
||||
>3000 : 3000
|
||||
>{ t: 5000 } : { t: number; }
|
||||
>t : number
|
||||
>5000 : 5000
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ interface Foo {
|
||||
}
|
||||
|
||||
class A<P extends Partial<Foo>> {
|
||||
props: Readonly<P>
|
||||
constructor(public props: Readonly<P>) {}
|
||||
doSomething() {
|
||||
this.props.foo && this.props.foo()
|
||||
}
|
||||
@@ -19,7 +19,7 @@ interface Banana {
|
||||
}
|
||||
|
||||
class Monkey<T extends Banana | undefined> {
|
||||
a: T;
|
||||
constructor(public a: T) {}
|
||||
render() {
|
||||
if (this.a) {
|
||||
this.a.color;
|
||||
@@ -96,7 +96,8 @@ var __extends = (this && this.__extends) || (function () {
|
||||
};
|
||||
})();
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
function A(props) {
|
||||
this.props = props;
|
||||
}
|
||||
A.prototype.doSomething = function () {
|
||||
this.props.foo && this.props.foo();
|
||||
@@ -104,7 +105,8 @@ var A = /** @class */ (function () {
|
||||
return A;
|
||||
}());
|
||||
var Monkey = /** @class */ (function () {
|
||||
function Monkey() {
|
||||
function Monkey(a) {
|
||||
this.a = a;
|
||||
}
|
||||
Monkey.prototype.render = function () {
|
||||
if (this.a) {
|
||||
|
||||
@@ -14,24 +14,24 @@ class A<P extends Partial<Foo>> {
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>Foo : Symbol(Foo, Decl(typeVariableTypeGuards.ts, 0, 0))
|
||||
|
||||
props: Readonly<P>
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
|
||||
constructor(public props: Readonly<P>) {}
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 7, 16))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
|
||||
>P : Symbol(P, Decl(typeVariableTypeGuards.ts, 6, 8))
|
||||
|
||||
doSomething() {
|
||||
>doSomething : Symbol(A.doSomething, Decl(typeVariableTypeGuards.ts, 7, 22))
|
||||
>doSomething : Symbol(A.doSomething, Decl(typeVariableTypeGuards.ts, 7, 45))
|
||||
|
||||
this.props.foo && this.props.foo()
|
||||
>this.props.foo : Symbol(foo, Decl(typeVariableTypeGuards.ts, 2, 15))
|
||||
>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
|
||||
>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 7, 16))
|
||||
>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1))
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 7, 16))
|
||||
>foo : Symbol(foo, Decl(typeVariableTypeGuards.ts, 2, 15))
|
||||
>this.props.foo : Symbol(foo, Decl(typeVariableTypeGuards.ts, 2, 15))
|
||||
>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
|
||||
>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 7, 16))
|
||||
>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1))
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
|
||||
>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 7, 16))
|
||||
>foo : Symbol(foo, Decl(typeVariableTypeGuards.ts, 2, 15))
|
||||
}
|
||||
}
|
||||
@@ -50,23 +50,23 @@ class Monkey<T extends Banana | undefined> {
|
||||
>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13))
|
||||
>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1))
|
||||
|
||||
a: T;
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
constructor(public a: T) {}
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13))
|
||||
|
||||
render() {
|
||||
>render : Symbol(Monkey.render, Decl(typeVariableTypeGuards.ts, 20, 9))
|
||||
>render : Symbol(Monkey.render, Decl(typeVariableTypeGuards.ts, 20, 31))
|
||||
|
||||
if (this.a) {
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
|
||||
this.a.color;
|
||||
>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
|
||||
}
|
||||
}
|
||||
@@ -86,15 +86,15 @@ class BigMonkey extends Monkey<BigBanana> {
|
||||
>render : Symbol(BigMonkey.render, Decl(typeVariableTypeGuards.ts, 31, 43))
|
||||
|
||||
if (this.a) {
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
|
||||
this.a.color;
|
||||
>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
|
||||
>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 20, 16))
|
||||
>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class A<P extends Partial<Foo>> {
|
||||
>Partial : Partial<T>
|
||||
>Foo : Foo
|
||||
|
||||
props: Readonly<P>
|
||||
constructor(public props: Readonly<P>) {}
|
||||
>props : Readonly<P>
|
||||
>Readonly : Readonly<T>
|
||||
>P : P
|
||||
@@ -52,7 +52,7 @@ class Monkey<T extends Banana | undefined> {
|
||||
>T : T
|
||||
>Banana : Banana
|
||||
|
||||
a: T;
|
||||
constructor(public a: T) {}
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ type Data<T> = {
|
||||
};
|
||||
|
||||
class Parent<M> {
|
||||
private data: Data<M>;
|
||||
constructor(private data: Data<M>) {}
|
||||
getData(): Data<M> {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Foo {
|
||||
}
|
||||
|
||||
class A<P extends Partial<Foo>> {
|
||||
props: Readonly<P>
|
||||
constructor(public props: Readonly<P>) {}
|
||||
doSomething() {
|
||||
this.props.foo && this.props.foo()
|
||||
}
|
||||
@@ -20,7 +20,7 @@ interface Banana {
|
||||
}
|
||||
|
||||
class Monkey<T extends Banana | undefined> {
|
||||
a: T;
|
||||
constructor(public a: T) {}
|
||||
render() {
|
||||
if (this.a) {
|
||||
this.a.color;
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Properties with non-undefined types require initialization
|
||||
|
||||
class C1 {
|
||||
a: number; // Error
|
||||
b: number | undefined;
|
||||
c: number | null; // Error
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks in ambient contexts
|
||||
|
||||
declare class C2 {
|
||||
a: number;
|
||||
b: number | undefined;
|
||||
c: number | null;
|
||||
d?: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for static members
|
||||
|
||||
class C3 {
|
||||
static a: number;
|
||||
static b: number | undefined;
|
||||
static c: number | null;
|
||||
static d?: number;
|
||||
}
|
||||
|
||||
// Initializer satisfies strict initialization check
|
||||
|
||||
class C4 {
|
||||
a = 0;
|
||||
b: number = 0;
|
||||
c: string = "abc";
|
||||
}
|
||||
|
||||
// Assignment in constructor satisfies strict initialization check
|
||||
|
||||
class C5 {
|
||||
a: number;
|
||||
constructor() {
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// All code paths must contain assignment
|
||||
|
||||
class C6 {
|
||||
a: number; // Error
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class C7 {
|
||||
a: number;
|
||||
constructor(cond: boolean) {
|
||||
if (cond) {
|
||||
this.a = 1;
|
||||
return;
|
||||
}
|
||||
this.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Properties with string literal names aren't checked
|
||||
|
||||
class C8 {
|
||||
a: number; // Error
|
||||
"b": number;
|
||||
0: number;
|
||||
}
|
||||
|
||||
// No strict initialization checks for abstract members
|
||||
|
||||
abstract class C9 {
|
||||
abstract a: number;
|
||||
abstract b: number | undefined;
|
||||
abstract c: number | null;
|
||||
abstract d?: number;
|
||||
}
|
||||
|
||||
// Properties with non-undefined types must be assigned before they can be accessed
|
||||
// within their constructor
|
||||
|
||||
class C10 {
|
||||
a: number;
|
||||
b: number;
|
||||
c?: number;
|
||||
constructor() {
|
||||
let x = this.a; // Error
|
||||
this.a = this.b; // Error
|
||||
this.b = x;
|
||||
let y = this.c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Suppress strict property initialization check
|
||||
|
||||
class C1 {
|
||||
a!: number;
|
||||
b: string; // Error
|
||||
}
|
||||
|
||||
// Suppress definite assignment check in constructor
|
||||
|
||||
class C2 {
|
||||
a!: number;
|
||||
constructor() {
|
||||
let x = this.a;
|
||||
}
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation, no initializer, no static modifier
|
||||
|
||||
class C3 {
|
||||
a! = 1;
|
||||
b!: number = 1;
|
||||
static c!: number;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare class C4 {
|
||||
a!: number;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted on abstract property
|
||||
|
||||
abstract class C5 {
|
||||
abstract a!: number;
|
||||
}
|
||||
|
||||
// Suppress definite assignment check for variable
|
||||
|
||||
function f1() {
|
||||
let x!: number;
|
||||
let y = x;
|
||||
var a!: number;
|
||||
var b = a;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
let x!: string | number;
|
||||
if (typeof x === "string") {
|
||||
let s: string = x;
|
||||
}
|
||||
else {
|
||||
let n: number = x;
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
let x!: number;
|
||||
const g = () => {
|
||||
x = 1;
|
||||
}
|
||||
g();
|
||||
let y = x;
|
||||
}
|
||||
|
||||
// Definite assignment assertion requires type annotation and no initializer
|
||||
|
||||
function f4() {
|
||||
let a!;
|
||||
let b! = 1;
|
||||
let c!: number = 1;
|
||||
}
|
||||
|
||||
// Definite assignment assertion not permitted in ambient context
|
||||
|
||||
declare let v1!: number;
|
||||
declare var v2!: number;
|
||||
@@ -8,7 +8,9 @@ declare class C<T> { t: T }
|
||||
// @Filename: badTypeArguments.js
|
||||
/** @param {C.<>} x */
|
||||
/** @param {C.<number,>} y */
|
||||
function f(x, y) {
|
||||
// @ts-ignore
|
||||
/** @param {C.<number,>} skipped */
|
||||
function f(x, y, skipped) {
|
||||
return x.t + y.t;
|
||||
}
|
||||
var x = f({ t: 1000 }, { t: 3000 });
|
||||
var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 });
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #20138
|
||||
|
||||
class C { }
|
||||
|
||||
function f1<T extends C>(v: T | string): void {
|
||||
if (v instanceof C) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const s: string = v;
|
||||
}
|
||||
}
|
||||
|
||||
class D { }
|
||||
|
||||
function f2<T extends C, U extends D>(v: T | U) {
|
||||
if (v instanceof C) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const y: U = v;
|
||||
}
|
||||
}
|
||||
|
||||
class E { x: string | undefined }
|
||||
|
||||
function f3<T extends E>(v: T | { x: string }) {
|
||||
if (v instanceof E) {
|
||||
const x: T = v;
|
||||
}
|
||||
else {
|
||||
const y: { x: string } = v;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
"outDir": "./built",
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"lib": ["dom", "es2017"]
|
||||
"lib": ["dom", "es2017"],
|
||||
"types": []
|
||||
},
|
||||
"include": [
|
||||
"./node_modules/chrome-devtools-frontend/front_end/**/*.js"
|
||||
|
||||
Reference in New Issue
Block a user