Skip to content

Commit a775006

Browse files
committed
Merge branch 'master' of https://github.com/Microsoft/TypeScript
2 parents 1f50056 + c563e83 commit a775006

File tree

73 files changed

+1905
-112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1905
-112
lines changed

src/compiler/checker.ts

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/compiler/diagnosticMessages.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@
227227
"category": "Error",
228228
"code": 1084
229229
},
230-
"Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o{0}'.": {
230+
"Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'.": {
231231
"category": "Error",
232232
"code": 1085
233233
},
@@ -2952,7 +2952,7 @@
29522952
"Resolution for module '{0}' was found in cache": {
29532953
"category": "Message",
29542954
"code": 6147
2955-
},
2955+
},
29562956
"Variable '{0}' implicitly has an '{1}' type.": {
29572957
"category": "Error",
29582958
"code": 7005
@@ -3243,7 +3243,7 @@
32433243
"category": "Message",
32443244
"code": 90015
32453245
},
3246-
"Octal literal types must use ES2015 syntax. Use the syntax '0o{0}'.": {
3246+
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
32473247
"category": "Error",
32483248
"code": 8017
32493249
}

0 commit comments

Comments
 (0)