@@ -636,11 +636,24 @@ namespace ts {
636
636
637
637
if (declaration.pos <= usage.pos) {
638
638
// 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;
642
654
}
643
655
656
+
644
657
// declaration is after usage
645
658
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
646
659
const container = getEnclosingBlockScopeContainer(declaration);
@@ -697,6 +710,16 @@ namespace ts {
697
710
}
698
711
return false;
699
712
}
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
+ }
700
723
}
701
724
702
725
// 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 {
1063
1086
1064
1087
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
1065
1088
1066
- if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(<Declaration>getAncestor( declaration, SyntaxKind.VariableDeclaration) , errorLocation)) {
1089
+ if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
1067
1090
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
1068
1091
}
1069
1092
}
@@ -6645,7 +6668,7 @@ namespace ts {
6645
6668
// Starting with the parent of the symbol's declaration, check if the mapper maps any of
6646
6669
// the type parameters introduced by enclosing declarations. We just pick the first
6647
6670
// 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];
6649
6672
while (node) {
6650
6673
switch (node.kind) {
6651
6674
case SyntaxKind.FunctionType:
@@ -6665,7 +6688,7 @@ namespace ts {
6665
6688
case SyntaxKind.ClassExpression:
6666
6689
case SyntaxKind.InterfaceDeclaration:
6667
6690
case SyntaxKind.TypeAliasDeclaration:
6668
- const declaration = <DeclarationWithTypeParameters> node;
6691
+ const declaration = node as DeclarationWithTypeParameters ;
6669
6692
if (declaration.typeParameters) {
6670
6693
for (const d of declaration.typeParameters) {
6671
6694
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
@@ -6680,6 +6703,14 @@ namespace ts {
6680
6703
}
6681
6704
}
6682
6705
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;
6683
6714
case SyntaxKind.ModuleDeclaration:
6684
6715
case SyntaxKind.SourceFile:
6685
6716
return false;
@@ -16891,7 +16922,7 @@ namespace ts {
16891
16922
if (!local.isReferenced && !local.exportSymbol) {
16892
16923
for (const declaration of local.declarations) {
16893
16924
if (!isAmbientModule(declaration)) {
16894
- error (declaration.name, Diagnostics._0_is_declared_but_never_used , local.name);
16925
+ errorUnusedLocal (declaration.name, local.name);
16895
16926
}
16896
16927
}
16897
16928
}
@@ -17149,7 +17180,8 @@ namespace ts {
17149
17180
// so we need to do a bit of extra work to check if reference is legal
17150
17181
const enclosingContainer = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
17151
17182
if (enclosingContainer === func) {
17152
- if (symbol.valueDeclaration.kind === SyntaxKind.Parameter) {
17183
+ if (symbol.valueDeclaration.kind === SyntaxKind.Parameter ||
17184
+ symbol.valueDeclaration.kind === SyntaxKind.BindingElement) {
17153
17185
// it is ok to reference parameter in initializer if either
17154
17186
// - parameter is located strictly on the left of current parameter declaration
17155
17187
if (symbol.valueDeclaration.pos < node.pos) {
@@ -21849,11 +21881,17 @@ namespace ts {
21849
21881
function checkGrammarNumericLiteral(node: NumericLiteral): boolean {
21850
21882
// Grammar checking
21851
21883
if (node.isOctalLiteral) {
21884
+ let diagnosticMessage: DiagnosticMessage | undefined;
21852
21885
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;
21854
21890
}
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);
21857
21895
}
21858
21896
}
21859
21897
}
0 commit comments