Merge branch 'master' into es6typings

Conflicts:
	tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.types
This commit is contained in:
Mohamed Hegazy
2014-12-01 16:51:10 -08:00
70 changed files with 860 additions and 69 deletions

View File

@@ -1608,6 +1608,8 @@ module ts {
return isDeclarationVisible(<Declaration>parent);
case SyntaxKind.Property:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Method:
if (node.flags & (NodeFlags.Private | NodeFlags.Protected)) {
// Private/protected properties/methods are not visible
@@ -1622,6 +1624,14 @@ module ts {
case SyntaxKind.Parameter:
case SyntaxKind.ModuleBlock:
case SyntaxKind.TypeParameter:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.TypeLiteral:
case SyntaxKind.TypeReference:
case SyntaxKind.ArrayType:
case SyntaxKind.TupleType:
case SyntaxKind.UnionType:
case SyntaxKind.ParenthesizedType:
return isDeclarationVisible(<Declaration>node.parent);
// Source file is always visible
@@ -5335,7 +5345,7 @@ module ts {
var templateExpression = <TemplateExpression>tagExpression.template;
var lastSpan = lastOrUndefined(templateExpression.templateSpans);
Debug.assert(lastSpan !== undefined); // we should always have at least one span.
callIsIncomplete = lastSpan.literal.kind === SyntaxKind.Missing || isUnterminatedTemplateEnd(lastSpan.literal);
callIsIncomplete = lastSpan.literal.kind === SyntaxKind.Missing || !!lastSpan.literal.isUnterminated;
}
else {
// If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
@@ -5343,7 +5353,7 @@ module ts {
// so we consider the call to be incomplete.
var templateLiteral = <LiteralExpression>tagExpression.template;
Debug.assert(templateLiteral.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
callIsIncomplete = isUnterminatedTemplateEnd(templateLiteral);
callIsIncomplete = !!templateLiteral.isUnterminated;
}
}
else {

View File

@@ -855,25 +855,6 @@ module ts {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
export function isUnterminatedTemplateEnd(node: LiteralExpression) {
Debug.assert(isTemplateLiteralKind(node.kind));
var sourceText = getSourceFileOfNode(node).text;
// If we're not at the EOF, we know we must be terminated.
if (node.end !== sourceText.length) {
return false;
}
// The literal can only be unterminated if it is a template tail or a no-sub template.
if (node.kind !== SyntaxKind.TemplateTail && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral) {
return false;
}
// If we didn't end in a backtick, we must still be in the middle of a template.
// If we did, make sure that it's not the *initial* backtick.
return sourceText.charCodeAt(node.end - 1) !== CharacterCodes.backtick || node.text.length === 0;
}
export function isModifier(token: SyntaxKind): boolean {
switch (token) {
case SyntaxKind.PublicKeyword:
@@ -1691,6 +1672,10 @@ module ts {
var text = scanner.getTokenValue();
node.text = internName ? internIdentifier(text) : text;
if (scanner.isUnterminated()) {
node.isUnterminated = true;
}
var tokenPos = scanner.getTokenPos();
nextToken();
finishNode(node);

View File

@@ -22,6 +22,7 @@ module ts {
hasPrecedingLineBreak(): boolean;
isIdentifier(): boolean;
isReservedWord(): boolean;
isUnterminated(): boolean;
reScanGreaterToken(): SyntaxKind;
reScanSlashToken(): SyntaxKind;
reScanTemplateToken(): SyntaxKind;
@@ -470,6 +471,7 @@ module ts {
var token: SyntaxKind;
var tokenValue: string;
var precedingLineBreak: boolean;
var tokenIsUnterminated: boolean;
function error(message: DiagnosticMessage): void {
if (onError) {
@@ -553,6 +555,7 @@ module ts {
while (true) {
if (pos >= len) {
result += text.substring(start, pos);
tokenIsUnterminated = true;
error(Diagnostics.Unterminated_string_literal);
break;
}
@@ -570,6 +573,7 @@ module ts {
}
if (isLineBreak(ch)) {
result += text.substring(start, pos);
tokenIsUnterminated = true;
error(Diagnostics.Unterminated_string_literal);
break;
}
@@ -593,6 +597,7 @@ module ts {
while (true) {
if (pos >= len) {
contents += text.substring(start, pos);
tokenIsUnterminated = true;
error(Diagnostics.Unterminated_template_literal);
resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail;
break;
@@ -780,6 +785,7 @@ module ts {
function scan(): SyntaxKind {
startPos = pos;
precedingLineBreak = false;
tokenIsUnterminated = false;
while (true) {
tokenPos = pos;
if (pos >= len) {
@@ -936,6 +942,7 @@ module ts {
continue;
}
else {
tokenIsUnterminated = !commentClosed;
return token = SyntaxKind.MultiLineCommentTrivia;
}
}
@@ -1113,12 +1120,14 @@ module ts {
// If we reach the end of a file, or hit a newline, then this is an unterminated
// regex. Report error and return what we have so far.
if (p >= len) {
tokenIsUnterminated = true;
error(Diagnostics.Unterminated_regular_expression_literal)
break;
}
var ch = text.charCodeAt(p);
if (isLineBreak(ch)) {
tokenIsUnterminated = true;
error(Diagnostics.Unterminated_regular_expression_literal)
break;
}
@@ -1211,6 +1220,7 @@ module ts {
hasPrecedingLineBreak: () => precedingLineBreak,
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
isUnterminated: () => tokenIsUnterminated,
reScanGreaterToken,
reScanSlashToken,
reScanTemplateToken,

View File

@@ -527,6 +527,7 @@ module ts {
// For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
export interface LiteralExpression extends PrimaryExpression {
text: string;
isUnterminated?: boolean;
}
export interface TemplateExpression extends PrimaryExpression {

1
src/lib/core.d.ts vendored
View File

@@ -836,6 +836,7 @@ interface RegExp {
interface RegExpConstructor {
new (pattern: string, flags?: string): RegExp;
(pattern: string, flags?: string): RegExp;
prototype: RegExp;
// Non-standard extensions
$1: string;

View File

@@ -631,6 +631,7 @@ interface Map<K, V> {
}
declare var Map: {
new <K, V>(): Map<K, V>;
prototype: Map<any, any>;
}
interface WeakMap<K, V> {
@@ -642,6 +643,7 @@ interface WeakMap<K, V> {
}
declare var WeakMap: {
new <K, V>(): WeakMap<K, V>;
prototype: WeakMap<any, any>;
}
interface Set<T> {
@@ -654,4 +656,5 @@ interface Set<T> {
}
declare var Set: {
new <T>(): Set<T>;
prototype: Set<any>;
}

View File

@@ -146,7 +146,11 @@ module ts.formatting {
if (lastTokenInfo && expectedScanAction === lastScanAction) {
// readTokenInfo was called before with the same expected scan action.
// No need to re-scan text, return existing 'lastTokenInfo'
return lastTokenInfo;
// it is ok to call fixTokenKind here since it does not affect
// what portion of text is consumed. In opposize rescanning can change it,
// i.e. for '>=' when originally scanner eats just one character
// and rescanning forces it to consume more.
return fixTokenKind(lastTokenInfo, n);
}
if (scanner.getStartPos() !== savedPos) {
@@ -207,11 +211,13 @@ module ts.formatting {
}
}
return lastTokenInfo = {
lastTokenInfo = {
leadingTrivia: leadingTrivia,
trailingTrivia: trailingTrivia,
token: token
}
return fixTokenKind(lastTokenInfo, n);
}
function isOnToken(): boolean {
@@ -219,5 +225,16 @@ module ts.formatting {
var startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
}
// when containing node in the tree is token
// but its kind differs from the kind that was returned by the scanner,
// then kind needs to be fixed. This might happen in cases
// when parser interprets token differently, i.e keyword treated as identifier
function fixTokenKind(tokenInfo: TokenInfo, container: Node): TokenInfo {
if (isToken(container) && tokenInfo.token.kind !== container.kind) {
tokenInfo.token.kind = container.kind;
}
return tokenInfo;
}
}
}

View File

@@ -2501,10 +2501,11 @@ module ts {
}
function isInStringOrRegularExpressionOrTemplateLiteral(previousToken: Node): boolean {
if (previousToken.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(previousToken.kind)) {
if (previousToken.kind === SyntaxKind.StringLiteral
|| previousToken.kind === SyntaxKind.RegularExpressionLiteral
|| isTemplateLiteralKind(previousToken.kind)) {
// The position has to be either: 1. entirely within the token text, or
// 2. at the end position, and the string literal is not terminated
// 2. at the end position of an unterminated token.
var start = previousToken.getStart();
var end = previousToken.getEnd();
@@ -2512,36 +2513,9 @@ module ts {
return true;
}
else if (position === end) {
var width = end - start;
var text = previousToken.getSourceFile().text;
// If the token is a single character, or its second-to-last charcter indicates an escape code,
// then we can immediately say that we are in the middle of an unclosed string.
if (width <= 1 || text.charCodeAt(end - 2) === CharacterCodes.backslash) {
return true;
}
// Now check if the last character is a closing character for the token.
switch (previousToken.kind) {
case SyntaxKind.StringLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
return text.charCodeAt(start) !== text.charCodeAt(end - 1);
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
return text.charCodeAt(end - 1) !== CharacterCodes.openBrace
|| text.charCodeAt(end - 2) !== CharacterCodes.$;
case SyntaxKind.TemplateTail:
return text.charCodeAt(end - 1) !== CharacterCodes.backtick;
}
return false;
return !!(<LiteralExpression>previousToken).isUnterminated;
}
}
else if (previousToken.kind === SyntaxKind.RegularExpressionLiteral) {
return previousToken.getStart() < position && position < previousToken.getEnd();
}
return false;
}
@@ -5665,23 +5639,29 @@ module ts {
addResult(end - start, classFromKind(token));
if (end >= text.length) {
// We're at the end.
if (token === SyntaxKind.StringLiteral) {
// Check to see if we finished up on a multiline string literal.
var tokenText = scanner.getTokenText();
if (tokenText.length > 0 && tokenText.charCodeAt(tokenText.length - 1) === CharacterCodes.backslash) {
var quoteChar = tokenText.charCodeAt(0);
result.finalLexState = quoteChar === CharacterCodes.doubleQuote
? EndOfLineState.InDoubleQuoteStringLiteral
: EndOfLineState.InSingleQuoteStringLiteral;
if (scanner.isUnterminated()) {
var lastCharIndex = tokenText.length - 1;
var 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) {
var quoteChar = tokenText.charCodeAt(0);
result.finalLexState = quoteChar === CharacterCodes.doubleQuote
? EndOfLineState.InDoubleQuoteStringLiteral
: EndOfLineState.InSingleQuoteStringLiteral;
}
}
}
else if (token === SyntaxKind.MultiLineCommentTrivia) {
// Check to see if the multiline comment was unclosed.
var tokenText = scanner.getTokenText()
if (!(tokenText.length > 3 && // need to avoid catching '/*/'
tokenText.charCodeAt(tokenText.length - 2) === CharacterCodes.asterisk &&
tokenText.charCodeAt(tokenText.length - 1) === CharacterCodes.slash)) {
if (scanner.isUnterminated()) {
result.finalLexState = EndOfLineState.InMultiLineCommentTrivia;
}
}

View File

@@ -296,7 +296,7 @@ module ts.SignatureHelp {
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
// If we're just after a template tail, don't show signature help.
if (node.kind === SyntaxKind.TemplateTail && position >= node.getEnd() && !isUnterminatedTemplateEnd(<LiteralExpression>node)) {
if (node.kind === SyntaxKind.TemplateTail && position >= node.getEnd() && !(<LiteralExpression>node).isUnterminated) {
return undefined;
}

View File

@@ -322,7 +322,7 @@ module ts {
}
export function isInsideTemplateLiteral(node: LiteralExpression, position: number) {
return (node.getStart() < position && position < node.getEnd())
|| (isUnterminatedTemplateEnd(node) && position === node.getEnd());
return isTemplateLiteralKind(node.kind)
&& (node.getStart() < position && position < node.getEnd()) || (!!node.isUnterminated && position === node.getEnd());
}
}