@@ -636,11 +636,24 @@ namespace ts {
636636
637637 if (declaration.pos <= usage.pos) {
638638 // declaration is before usage
639- // still might be illegal if usage is in the initializer of the variable declaration
640- return declaration.kind !== SyntaxKind.VariableDeclaration ||
641- !isImmediatelyUsedInInitializerOfBlockScopedVariable(<VariableDeclaration>declaration, usage);
639+ if (declaration.kind === SyntaxKind.BindingElement) {
640+ // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
641+ const errorBindingElement = getAncestor(usage, SyntaxKind.BindingElement) as BindingElement;
642+ if (errorBindingElement) {
643+ return getAncestorBindingPattern(errorBindingElement) !== getAncestorBindingPattern(declaration) ||
644+ declaration.pos < errorBindingElement.pos;
645+ }
646+ // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
647+ return isBlockScopedNameDeclaredBeforeUse(getAncestor(declaration, SyntaxKind.VariableDeclaration) as Declaration, usage);
648+ }
649+ else if (declaration.kind === SyntaxKind.VariableDeclaration) {
650+ // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
651+ return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage);
652+ }
653+ return true;
642654 }
643655
656+
644657 // declaration is after usage
645658 // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
646659 const container = getEnclosingBlockScopeContainer(declaration);
@@ -697,6 +710,16 @@ namespace ts {
697710 }
698711 return false;
699712 }
713+
714+ function getAncestorBindingPattern(node: Node): BindingPattern {
715+ while (node) {
716+ if (isBindingPattern(node)) {
717+ return node;
718+ }
719+ node = node.parent;
720+ }
721+ return undefined;
722+ }
700723 }
701724
702725 // Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
@@ -1063,7 +1086,7 @@ namespace ts {
10631086
10641087 Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
10651088
1066- if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(<Declaration>getAncestor( declaration, SyntaxKind.VariableDeclaration) , errorLocation)) {
1089+ if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
10671090 error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
10681091 }
10691092 }
@@ -6645,7 +6668,7 @@ namespace ts {
66456668 // Starting with the parent of the symbol's declaration, check if the mapper maps any of
66466669 // the type parameters introduced by enclosing declarations. We just pick the first
66476670 // declaration since multiple declarations will all have the same parent anyway.
6648- let node = symbol.declarations[0].parent ;
6671+ let node: Node = symbol.declarations[0];
66496672 while (node) {
66506673 switch (node.kind) {
66516674 case SyntaxKind.FunctionType:
@@ -6665,7 +6688,7 @@ namespace ts {
66656688 case SyntaxKind.ClassExpression:
66666689 case SyntaxKind.InterfaceDeclaration:
66676690 case SyntaxKind.TypeAliasDeclaration:
6668- const declaration = <DeclarationWithTypeParameters> node;
6691+ const declaration = node as DeclarationWithTypeParameters ;
66696692 if (declaration.typeParameters) {
66706693 for (const d of declaration.typeParameters) {
66716694 if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
@@ -6680,6 +6703,14 @@ namespace ts {
66806703 }
66816704 }
66826705 break;
6706+ case SyntaxKind.JSDocFunctionType:
6707+ const func = node as JSDocFunctionType;
6708+ for (const p of func.parameters) {
6709+ if (contains(mappedTypes, getTypeOfNode(p))) {
6710+ return true;
6711+ }
6712+ }
6713+ break;
66836714 case SyntaxKind.ModuleDeclaration:
66846715 case SyntaxKind.SourceFile:
66856716 return false;
@@ -16891,7 +16922,7 @@ namespace ts {
1689116922 if (!local.isReferenced && !local.exportSymbol) {
1689216923 for (const declaration of local.declarations) {
1689316924 if (!isAmbientModule(declaration)) {
16894- error (declaration.name, Diagnostics._0_is_declared_but_never_used , local.name);
16925+ errorUnusedLocal (declaration.name, local.name);
1689516926 }
1689616927 }
1689716928 }
@@ -17149,7 +17180,8 @@ namespace ts {
1714917180 // so we need to do a bit of extra work to check if reference is legal
1715017181 const enclosingContainer = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
1715117182 if (enclosingContainer === func) {
17152- if (symbol.valueDeclaration.kind === SyntaxKind.Parameter) {
17183+ if (symbol.valueDeclaration.kind === SyntaxKind.Parameter ||
17184+ symbol.valueDeclaration.kind === SyntaxKind.BindingElement) {
1715317185 // it is ok to reference parameter in initializer if either
1715417186 // - parameter is located strictly on the left of current parameter declaration
1715517187 if (symbol.valueDeclaration.pos < node.pos) {
@@ -21849,11 +21881,17 @@ namespace ts {
2184921881 function checkGrammarNumericLiteral(node: NumericLiteral): boolean {
2185021882 // Grammar checking
2185121883 if (node.isOctalLiteral) {
21884+ let diagnosticMessage: DiagnosticMessage | undefined;
2185221885 if (languageVersion >= ScriptTarget.ES5) {
21853- return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0o_0, node.text);
21886+ diagnosticMessage = Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
21887+ }
21888+ else if (isChildOfLiteralType(node)) {
21889+ diagnosticMessage = Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
2185421890 }
21855- if (isChildOfLiteralType(node)) {
21856- return grammarErrorOnNode(node, Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0o_0, node.text);
21891+ if (diagnosticMessage) {
21892+ const withMinus = isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.MinusToken;
21893+ const literal = `${withMinus ? "-" : ""}0o${node.text}`;
21894+ return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
2185721895 }
2185821896 }
2185921897 }
0 commit comments