mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into newLineClassification
This commit is contained in:
@@ -68,6 +68,7 @@ var servicesSources = [
|
||||
"navigateTo.ts",
|
||||
"navigationBar.ts",
|
||||
"outliningElementsCollector.ts",
|
||||
"patternMatcher.ts",
|
||||
"services.ts",
|
||||
"shims.ts",
|
||||
"signatureHelp.ts",
|
||||
@@ -139,7 +140,8 @@ var harnessSources = [
|
||||
"incrementalParser.ts",
|
||||
"services/colorization.ts",
|
||||
"services/documentRegistry.ts",
|
||||
"services/preProcessFile.ts"
|
||||
"services/preProcessFile.ts",
|
||||
"services/patternMatcher.ts"
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
|
||||
+16
-16
@@ -3409,7 +3409,7 @@ module ts {
|
||||
return isContextSensitive((<ConditionalExpression>node).whenTrue) ||
|
||||
isContextSensitive((<ConditionalExpression>node).whenFalse);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return (<BinaryExpression>node).operator === SyntaxKind.BarBarToken &&
|
||||
return (<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken &&
|
||||
(isContextSensitive((<BinaryExpression>node).left) || isContextSensitive((<BinaryExpression>node).right));
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return isContextSensitive((<PropertyAssignment>node).initializer);
|
||||
@@ -4591,7 +4591,7 @@ module ts {
|
||||
return links.assignmentChecks[symbol.id] = isAssignedIn(node);
|
||||
|
||||
function isAssignedInBinaryExpression(node: BinaryExpression) {
|
||||
if (node.operator >= SyntaxKind.FirstAssignment && node.operator <= SyntaxKind.LastAssignment) {
|
||||
if (node.operatorToken.kind >= SyntaxKind.FirstAssignment && node.operatorToken.kind <= SyntaxKind.LastAssignment) {
|
||||
var n = node.left;
|
||||
while (n.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
n = (<ParenthesizedExpression>n).expression;
|
||||
@@ -4724,10 +4724,10 @@ module ts {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
// In the right operand of an && or ||, narrow based on left operand
|
||||
if (child === (<BinaryExpression>node).right) {
|
||||
if ((<BinaryExpression>node).operator === SyntaxKind.AmpersandAmpersandToken) {
|
||||
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
|
||||
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ true);
|
||||
}
|
||||
else if ((<BinaryExpression>node).operator === SyntaxKind.BarBarToken) {
|
||||
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken) {
|
||||
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ false);
|
||||
}
|
||||
}
|
||||
@@ -4765,7 +4765,7 @@ module ts {
|
||||
return type;
|
||||
}
|
||||
var typeInfo = primitiveTypeInfo[right.text];
|
||||
if (expr.operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
if (expr.operatorToken.kind === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
if (assumeTrue) {
|
||||
@@ -4855,7 +4855,7 @@ module ts {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
var operator = (<BinaryExpression>expr).operator;
|
||||
var operator = (<BinaryExpression>expr).operatorToken.kind;
|
||||
if (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
return narrowTypeByEquality(type, <BinaryExpression>expr, assumeTrue);
|
||||
}
|
||||
@@ -5202,7 +5202,7 @@ module ts {
|
||||
|
||||
function getContextualTypeForBinaryOperand(node: Expression): Type {
|
||||
var binaryExpression = <BinaryExpression>node.parent;
|
||||
var operator = binaryExpression.operator;
|
||||
var operator = binaryExpression.operatorToken.kind;
|
||||
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
|
||||
if (node === binaryExpression.right) {
|
||||
@@ -5452,7 +5452,7 @@ module ts {
|
||||
// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'.
|
||||
function isAssignmentTarget(node: Node): boolean {
|
||||
var parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operator === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node) {
|
||||
if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node) {
|
||||
return true;
|
||||
}
|
||||
if (parent.kind === SyntaxKind.PropertyAssignment) {
|
||||
@@ -7108,7 +7108,7 @@ module ts {
|
||||
}
|
||||
|
||||
function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operator === SyntaxKind.EqualsToken) {
|
||||
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
checkBinaryExpression(<BinaryExpression>target, contextualMapper);
|
||||
target = (<BinaryExpression>target).left;
|
||||
}
|
||||
@@ -7131,13 +7131,13 @@ module ts {
|
||||
|
||||
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
|
||||
// Grammar checking
|
||||
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operator)) {
|
||||
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
|
||||
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
// Assignment operator(11.13) or of a PostfixExpression(11.3)
|
||||
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.left);
|
||||
}
|
||||
|
||||
var operator = node.operator;
|
||||
var operator = node.operatorToken.kind;
|
||||
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
|
||||
}
|
||||
@@ -7178,8 +7178,8 @@ module ts {
|
||||
// try and return them a helpful suggestion
|
||||
if ((leftType.flags & TypeFlags.Boolean) &&
|
||||
(rightType.flags & TypeFlags.Boolean) &&
|
||||
(suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) {
|
||||
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator));
|
||||
(suggestedOperator = getSuggestedBooleanOperator(node.operatorToken.kind)) !== undefined) {
|
||||
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operatorToken.kind), tokenToString(suggestedOperator));
|
||||
}
|
||||
else {
|
||||
// otherwise just check each operand separately and report errors as normal
|
||||
@@ -7312,7 +7312,7 @@ module ts {
|
||||
}
|
||||
|
||||
function reportOperatorError() {
|
||||
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operator), typeToString(leftType), typeToString(rightType));
|
||||
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9252,7 +9252,7 @@ module ts {
|
||||
if (right === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
switch ((<BinaryExpression>e).operator) {
|
||||
switch ((<BinaryExpression>e).operatorToken.kind) {
|
||||
case SyntaxKind.BarToken: return left | right;
|
||||
case SyntaxKind.AmpersandToken: return left & right;
|
||||
case SyntaxKind.GreaterThanGreaterThanToken: return left >> right;
|
||||
@@ -10827,7 +10827,7 @@ module ts {
|
||||
}
|
||||
|
||||
var computedPropertyName = <ComputedPropertyName>node;
|
||||
if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>computedPropertyName.expression).operator === SyntaxKind.CommaToken) {
|
||||
if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>computedPropertyName.expression).operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
return grammarErrorOnNode(computedPropertyName.expression, Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
|
||||
}
|
||||
}
|
||||
|
||||
+240
-120
@@ -1758,8 +1758,8 @@ module ts {
|
||||
lastRecordedSourceMapSpan.emittedLine != emittedLine ||
|
||||
lastRecordedSourceMapSpan.emittedColumn != emittedColumn ||
|
||||
(lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
|
||||
(lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
|
||||
(lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
|
||||
(lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
|
||||
(lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
|
||||
// Encode the last recordedSpan before assigning new
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
|
||||
@@ -2080,6 +2080,52 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitLinePreservingList(parent: Node, nodes: NodeArray<Node>, allowTrailingComma: boolean, spacesBetweenBraces: boolean) {
|
||||
Debug.assert(nodes.length > 0);
|
||||
|
||||
increaseIndent();
|
||||
|
||||
if (nodeStartPositionsAreOnSameLine(parent, nodes[0])) {
|
||||
if (spacesBetweenBraces) {
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
}
|
||||
|
||||
for (var i = 0, n = nodes.length; i < n; i++) {
|
||||
if (i) {
|
||||
if (nodeEndIsOnSameLineAsNodeStart(nodes[i - 1], nodes[i])) {
|
||||
write(", ");
|
||||
}
|
||||
else {
|
||||
write(",");
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
emit(nodes[i]);
|
||||
}
|
||||
|
||||
var closeTokenIsOnSameLineAsLastElement = nodeEndPositionsAreOnSameLine(parent, lastOrUndefined(nodes));
|
||||
|
||||
if (nodes.hasTrailingComma && allowTrailingComma) {
|
||||
write(",");
|
||||
}
|
||||
|
||||
decreaseIndent();
|
||||
|
||||
if (closeTokenIsOnSameLineAsLastElement) {
|
||||
if (spacesBetweenBraces) {
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function emitList(nodes: Node[], start: number, count: number, multiLine: boolean, trailingComma: boolean) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
if (multiLine) {
|
||||
@@ -2135,7 +2181,7 @@ module ts {
|
||||
function emitLiteral(node: LiteralExpression) {
|
||||
var text = languageVersion < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind) ? getTemplateLiteralAsStringLiteral(node) :
|
||||
node.parent ? getSourceTextOfNodeFromSourceFile(currentSourceFile, node) :
|
||||
node.text;
|
||||
node.text;
|
||||
if (compilerOptions.sourceMap && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
|
||||
writer.writeLiteral(text);
|
||||
}
|
||||
@@ -2261,7 +2307,7 @@ module ts {
|
||||
// spread ('...') unary operators that are anticipated for ES6.
|
||||
switch (expression.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
switch ((<BinaryExpression>expression).operator) {
|
||||
switch ((<BinaryExpression>expression).operatorToken.kind) {
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.PercentToken:
|
||||
@@ -2480,22 +2526,18 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isSpreadElementExpression(node: Node) {
|
||||
return node.kind === SyntaxKind.SpreadElementExpression;
|
||||
}
|
||||
|
||||
function emitArrayLiteral(node: ArrayLiteralExpression) {
|
||||
var elements = node.elements;
|
||||
if (elements.length === 0) {
|
||||
write("[]");
|
||||
}
|
||||
else if (languageVersion >= ScriptTarget.ES6) {
|
||||
else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) {
|
||||
write("[");
|
||||
var multiLine = (node.flags & NodeFlags.MultiLine) !== 0;
|
||||
if (multiLine) {
|
||||
increaseIndent();
|
||||
}
|
||||
emitList(elements, 0, elements.length, /*multiLine*/ multiLine,
|
||||
/*trailingComma*/ elements.hasTrailingComma);
|
||||
if (multiLine) {
|
||||
decreaseIndent();
|
||||
}
|
||||
emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces:*/ false);
|
||||
write("]");
|
||||
}
|
||||
else {
|
||||
@@ -2504,32 +2546,6 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitObjectLiteralBody(node: ObjectLiteralExpression, numElements: number) {
|
||||
write("{");
|
||||
|
||||
var multiLine = (node.flags & NodeFlags.MultiLine) !== 0;
|
||||
|
||||
if (numElements > 0) {
|
||||
var properties = node.properties;
|
||||
if (!multiLine) {
|
||||
write(" ");
|
||||
}
|
||||
else {
|
||||
increaseIndent();
|
||||
}
|
||||
emitList(properties, 0, numElements, /*multiLine*/ multiLine,
|
||||
/*trailingComma*/ properties.hasTrailingComma && languageVersion >= ScriptTarget.ES5);
|
||||
if (!multiLine) {
|
||||
write(" ");
|
||||
}
|
||||
else {
|
||||
decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
write("}");
|
||||
}
|
||||
|
||||
function createSynthesizedNode(kind: SyntaxKind): Node {
|
||||
var node = createNode(kind);
|
||||
node.pos = -1;
|
||||
@@ -2665,7 +2681,7 @@ module ts {
|
||||
|
||||
function createBinaryExpression(left: Expression, operator: SyntaxKind, right: Expression): BinaryExpression {
|
||||
var result = <BinaryExpression>createSynthesizedNode(SyntaxKind.BinaryExpression);
|
||||
result.operator = operator;
|
||||
result.operatorToken = createSynthesizedNode(operator);
|
||||
result.left = left;
|
||||
result.right = right;
|
||||
|
||||
@@ -2759,7 +2775,14 @@ module ts {
|
||||
|
||||
// Ordinary case: either the object has no computed properties
|
||||
// or we're compiling with an ES6+ target.
|
||||
emitObjectLiteralBody(node, properties.length);
|
||||
write("{");
|
||||
|
||||
var properties = node.properties;
|
||||
if (properties.length) {
|
||||
emitLinePreservingList(node, properties, /*allowTrailingComma:*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces:*/ true)
|
||||
}
|
||||
|
||||
write("}");
|
||||
}
|
||||
|
||||
function emitComputedPropertyName(node: ComputedPropertyName) {
|
||||
@@ -3039,19 +3062,84 @@ module ts {
|
||||
}
|
||||
|
||||
function emitBinaryExpression(node: BinaryExpression) {
|
||||
if (languageVersion < ScriptTarget.ES6 && node.operator === SyntaxKind.EqualsToken &&
|
||||
if (languageVersion < ScriptTarget.ES6 && node.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
emitDestructuring(node);
|
||||
}
|
||||
else {
|
||||
emit(node.left);
|
||||
if (node.operator !== SyntaxKind.CommaToken) write(" ");
|
||||
write(tokenToString(node.operator));
|
||||
write(" ");
|
||||
|
||||
if (node.operatorToken.kind !== SyntaxKind.CommaToken) {
|
||||
write(" ");
|
||||
}
|
||||
|
||||
write(tokenToString(node.operatorToken.kind));
|
||||
|
||||
// We'd like to preserve newlines found in the original binary expression. i.e. if a user has:
|
||||
//
|
||||
// Foo() ||
|
||||
// Bar();
|
||||
//
|
||||
// Then we'd like to emit it as such. It seems like we'd only need to check for a newline and
|
||||
// then just indent and emit. However, that will lead to a problem with deeply nested code.
|
||||
// i.e. if you have:
|
||||
//
|
||||
// Foo() ||
|
||||
// Bar() ||
|
||||
// Baz();
|
||||
//
|
||||
// Then we don't want to emit it as:
|
||||
//
|
||||
// Foo() ||
|
||||
// Bar() ||
|
||||
// Baz();
|
||||
//
|
||||
// So we only indent if the right side of the binary expression starts further in on the line
|
||||
// versus the left.
|
||||
var operatorEnd = getLineAndCharacterOfPosition(currentSourceFile, node.operatorToken.end);
|
||||
var rightStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.right.pos));
|
||||
|
||||
// Check if the right expression is on a different line versus the operator itself. If so,
|
||||
// we'll emit newline.
|
||||
var onDifferentLine = operatorEnd.line !== rightStart.line;
|
||||
if (onDifferentLine) {
|
||||
// Also, if the right expression starts further in on the line than the left, then we'll indent.
|
||||
var exprStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
|
||||
var firstCharOfExpr = getFirstNonWhitespaceCharacterIndexOnLine(exprStart.line);
|
||||
var shouldIndent = rightStart.character > firstCharOfExpr;
|
||||
|
||||
if (shouldIndent) {
|
||||
increaseIndent();
|
||||
}
|
||||
|
||||
writeLine();
|
||||
}
|
||||
else {
|
||||
write(" ");
|
||||
}
|
||||
|
||||
emit(node.right);
|
||||
|
||||
if (shouldIndent) {
|
||||
decreaseIndent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstNonWhitespaceCharacterIndexOnLine(line: number): number {
|
||||
var lineStart = getLineStarts(currentSourceFile)[line];
|
||||
var text = currentSourceFile.text;
|
||||
|
||||
for (var i = lineStart; i < text.length; i++) {
|
||||
var ch = text.charCodeAt(i);
|
||||
if (!isWhiteSpace(text.charCodeAt(i)) || isLineBreak(ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i - lineStart;
|
||||
}
|
||||
|
||||
function emitConditionalExpression(node: ConditionalExpression) {
|
||||
emit(node.condition);
|
||||
write(" ? ");
|
||||
@@ -3060,7 +3148,7 @@ module ts {
|
||||
emit(node.whenFalse);
|
||||
}
|
||||
|
||||
function isSingleLineBlock(node: Node) {
|
||||
function isSingleLineEmptyBlock(node: Node) {
|
||||
if (node && node.kind === SyntaxKind.Block) {
|
||||
var block = <Block>node;
|
||||
return block.statements.length === 0 && nodeEndIsOnSameLineAsNodeStart(block, block);
|
||||
@@ -3068,7 +3156,7 @@ module ts {
|
||||
}
|
||||
|
||||
function emitBlock(node: Block) {
|
||||
if (isSingleLineBlock(node)) {
|
||||
if (isSingleLineEmptyBlock(node)) {
|
||||
emitToken(SyntaxKind.OpenBraceToken, node.pos);
|
||||
write(" ");
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.statements.end);
|
||||
@@ -3248,11 +3336,16 @@ module ts {
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.clauses.end);
|
||||
}
|
||||
|
||||
function isOnSameLine(node1: Node, node2: Node) {
|
||||
function nodeStartPositionsAreOnSameLine(node1: Node, node2: Node) {
|
||||
return getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node1.pos)) ===
|
||||
getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node2.pos));
|
||||
}
|
||||
|
||||
function nodeEndPositionsAreOnSameLine(node1: Node, node2: Node) {
|
||||
return getLineOfLocalPosition(currentSourceFile, node1.end) ===
|
||||
getLineOfLocalPosition(currentSourceFile, node2.end);
|
||||
}
|
||||
|
||||
function nodeEndIsOnSameLineAsNodeStart(node1: Node, node2: Node) {
|
||||
return getLineOfLocalPosition(currentSourceFile, node1.end) ===
|
||||
getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node2.pos));
|
||||
@@ -3267,7 +3360,7 @@ module ts {
|
||||
else {
|
||||
write("default:");
|
||||
}
|
||||
if (node.statements.length === 1 && isOnSameLine(node, node.statements[0])) {
|
||||
if (node.statements.length === 1 && nodeStartPositionsAreOnSameLine(node, node.statements[0])) {
|
||||
write(" ");
|
||||
emit(node.statements[0]);
|
||||
}
|
||||
@@ -3388,7 +3481,7 @@ module ts {
|
||||
// Return the expression 'value === void 0 ? defaultValue : value'
|
||||
var equals = <BinaryExpression>createNode(SyntaxKind.BinaryExpression);
|
||||
equals.left = value;
|
||||
equals.operator = SyntaxKind.EqualsEqualsEqualsToken;
|
||||
equals.operatorToken = createNode(SyntaxKind.EqualsEqualsEqualsToken);
|
||||
equals.right = createVoidZero();
|
||||
var cond = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression);
|
||||
cond.condition = equals;
|
||||
@@ -3471,7 +3564,7 @@ module ts {
|
||||
}
|
||||
|
||||
function emitDestructuringAssignment(target: Expression, value: Expression) {
|
||||
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operator === SyntaxKind.EqualsToken) {
|
||||
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
value = createDefaultValueCheck(value,(<BinaryExpression>target).right);
|
||||
target = (<BinaryExpression>target).left;
|
||||
}
|
||||
@@ -3757,77 +3850,14 @@ module ts {
|
||||
emitSignatureParameters(node);
|
||||
}
|
||||
|
||||
if (isSingleLineBlock(node.body)) {
|
||||
if (isSingleLineEmptyBlock(node.body) || !node.body) {
|
||||
write(" { }");
|
||||
}
|
||||
else if (node.body.kind === SyntaxKind.Block) {
|
||||
emitBlockFunctionBody(node, <Block>node.body);
|
||||
}
|
||||
else {
|
||||
write(" {");
|
||||
scopeEmitStart(node);
|
||||
|
||||
if (!node.body) {
|
||||
writeLine();
|
||||
write("}");
|
||||
}
|
||||
else {
|
||||
increaseIndent();
|
||||
|
||||
emitDetachedComments(node.body.kind === SyntaxKind.Block ? (<Block>node.body).statements : node.body);
|
||||
|
||||
var startIndex = 0;
|
||||
if (node.body.kind === SyntaxKind.Block) {
|
||||
startIndex = emitDirectivePrologues((<Block>node.body).statements, /*startWithNewLine*/ true);
|
||||
}
|
||||
var outPos = writer.getTextPos();
|
||||
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitDefaultValueAssignments(node);
|
||||
emitRestParameter(node);
|
||||
if (node.body.kind !== SyntaxKind.Block && outPos === writer.getTextPos()) {
|
||||
decreaseIndent();
|
||||
write(" ");
|
||||
emitStart(node.body);
|
||||
write("return ");
|
||||
|
||||
// Don't emit comments on this body. We'll have already taken care of it above
|
||||
// when we called emitDetachedComments.
|
||||
emitNode(node.body, /*disableComments:*/ true);
|
||||
emitEnd(node.body);
|
||||
write(";");
|
||||
emitTempDeclarations(/*newLine*/ false);
|
||||
write(" ");
|
||||
emitStart(node.body);
|
||||
write("}");
|
||||
emitEnd(node.body);
|
||||
}
|
||||
else {
|
||||
if (node.body.kind === SyntaxKind.Block) {
|
||||
emitLinesStartingAt((<Block>node.body).statements, startIndex);
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
emitLeadingComments(node.body);
|
||||
write("return ");
|
||||
emit(node.body, /*disableComments:*/ true);
|
||||
write(";");
|
||||
emitTrailingComments(node.body);
|
||||
}
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
writeLine();
|
||||
if (node.body.kind === SyntaxKind.Block) {
|
||||
emitLeadingCommentsOfPosition((<Block>node.body).statements.end);
|
||||
decreaseIndent();
|
||||
emitToken(SyntaxKind.CloseBraceToken, (<Block>node.body).statements.end);
|
||||
}
|
||||
else {
|
||||
decreaseIndent();
|
||||
emitStart(node.body);
|
||||
write("}");
|
||||
emitEnd(node.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scopeEmitEnd();
|
||||
emitExpressionFunctionBody(node, <Expression>node.body);
|
||||
}
|
||||
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
@@ -3839,11 +3869,101 @@ module ts {
|
||||
emitEnd(node);
|
||||
write(";");
|
||||
}
|
||||
|
||||
tempCount = saveTempCount;
|
||||
tempVariables = saveTempVariables;
|
||||
tempParameters = saveTempParameters;
|
||||
}
|
||||
|
||||
// Returns true if any preamble code was emitted.
|
||||
function emitFunctionBodyPreamble(node: FunctionLikeDeclaration): void {
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitDefaultValueAssignments(node);
|
||||
emitRestParameter(node);
|
||||
}
|
||||
|
||||
function emitExpressionFunctionBody(node: FunctionLikeDeclaration, body: Expression) {
|
||||
write(" {");
|
||||
scopeEmitStart(node);
|
||||
|
||||
increaseIndent();
|
||||
var outPos = writer.getTextPos();
|
||||
emitDetachedComments(node.body);
|
||||
emitFunctionBodyPreamble(node);
|
||||
var preambleEmitted = writer.getTextPos() !== outPos;
|
||||
decreaseIndent();
|
||||
|
||||
// If we didn't have to emit any preamble code, then attempt to keep the arrow
|
||||
// function on one line.
|
||||
if (!preambleEmitted && nodeStartPositionsAreOnSameLine(node, body)) {
|
||||
write(" ");
|
||||
emitStart(body);
|
||||
write("return ");
|
||||
|
||||
// Don't emit comments on this body. We'll have already taken care of it above
|
||||
// when we called emitDetachedComments.
|
||||
emitNode(body, /*disableComments:*/ true);
|
||||
emitEnd(body);
|
||||
write(";");
|
||||
emitTempDeclarations(/*newLine*/ false);
|
||||
write(" ");
|
||||
}
|
||||
else {
|
||||
increaseIndent();
|
||||
writeLine();
|
||||
emitLeadingComments(node.body);
|
||||
write("return ");
|
||||
emit(node.body, /*disableComments:*/ true);
|
||||
write(";");
|
||||
emitTrailingComments(node.body);
|
||||
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
}
|
||||
|
||||
emitStart(node.body);
|
||||
write("}");
|
||||
emitEnd(node.body);
|
||||
|
||||
scopeEmitEnd();
|
||||
}
|
||||
|
||||
function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) {
|
||||
write(" {");
|
||||
scopeEmitStart(node);
|
||||
|
||||
var outPos = writer.getTextPos();
|
||||
increaseIndent();
|
||||
emitDetachedComments(body.statements);
|
||||
var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
|
||||
emitFunctionBodyPreamble(node);
|
||||
decreaseIndent();
|
||||
var preambleEmitted = writer.getTextPos() !== outPos;
|
||||
|
||||
if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)) {
|
||||
for (var i = 0, n = body.statements.length; i < n; i++) {
|
||||
write(" ");
|
||||
emit(body.statements[i]);
|
||||
}
|
||||
emitTempDeclarations(/*newLine*/ false);
|
||||
write(" ");
|
||||
emitLeadingCommentsOfPosition(body.statements.end);
|
||||
}
|
||||
else {
|
||||
increaseIndent();
|
||||
emitLinesStartingAt(body.statements, startIndex);
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
|
||||
writeLine();
|
||||
emitLeadingCommentsOfPosition(body.statements.end);
|
||||
decreaseIndent();
|
||||
}
|
||||
|
||||
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
|
||||
scopeEmitEnd();
|
||||
}
|
||||
|
||||
function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement {
|
||||
if (ctor.body) {
|
||||
var statement = (<Block>ctor.body).statements[0];
|
||||
|
||||
+14
-18
@@ -152,6 +152,7 @@ module ts {
|
||||
return visitNode(cbNode, (<PostfixUnaryExpression>node).operand);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitNode(cbNode, (<BinaryExpression>node).left) ||
|
||||
visitNode(cbNode, (<BinaryExpression>node).operatorToken) ||
|
||||
visitNode(cbNode, (<BinaryExpression>node).right);
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return visitNode(cbNode, (<ConditionalExpression>node).condition) ||
|
||||
@@ -1311,6 +1312,12 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseTokenNode<T extends Node>(): T {
|
||||
var node = <T>createNode(token);
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function canParseSemicolon() {
|
||||
// If there's a real semicolon, then we can always parse it out.
|
||||
if (token === SyntaxKind.SemicolonToken) {
|
||||
@@ -2084,14 +2091,6 @@ module ts {
|
||||
return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function parseTokenNode<T extends Node>(): T {
|
||||
var node = <T>createNode(token);
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTemplateExpression(): TemplateExpression {
|
||||
var template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
|
||||
|
||||
@@ -2801,8 +2800,9 @@ module ts {
|
||||
// Expression[in] , AssignmentExpression[in]
|
||||
|
||||
var expr = parseAssignmentExpressionOrHigher();
|
||||
while (parseOptional(SyntaxKind.CommaToken)) {
|
||||
expr = makeBinaryExpression(expr, SyntaxKind.CommaToken, parseAssignmentExpressionOrHigher());
|
||||
var operatorToken: Node;
|
||||
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
|
||||
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
@@ -2881,9 +2881,7 @@ module ts {
|
||||
// Note: we call reScanGreaterToken so that we get an appropriately merged token
|
||||
// for cases like > > = becoming >>=
|
||||
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
|
||||
var operator = token;
|
||||
nextToken();
|
||||
return makeBinaryExpression(expr, operator, parseAssignmentExpressionOrHigher());
|
||||
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
|
||||
// It wasn't an assignment or a lambda. This is a conditional expression:
|
||||
@@ -3187,9 +3185,7 @@ module ts {
|
||||
break;
|
||||
}
|
||||
|
||||
var operator = token;
|
||||
nextToken();
|
||||
leftOperand = makeBinaryExpression(leftOperand, operator, parseBinaryExpressionOrHigher(newPrecedence));
|
||||
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
|
||||
}
|
||||
|
||||
return leftOperand;
|
||||
@@ -3245,10 +3241,10 @@ module ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function makeBinaryExpression(left: Expression, operator: SyntaxKind, right: Expression): BinaryExpression {
|
||||
function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
|
||||
var node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, left.pos);
|
||||
node.left = left;
|
||||
node.operator = operator;
|
||||
node.operatorToken = operatorToken;
|
||||
node.right = right;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget) {
|
||||
/* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget) {
|
||||
return languageVersion >= ScriptTarget.ES5 ?
|
||||
lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
|
||||
lookupInUnicodeMap(code, unicodeES3IdentifierStart);
|
||||
|
||||
@@ -623,7 +623,7 @@ module ts {
|
||||
|
||||
export interface BinaryExpression extends Expression {
|
||||
left: Expression;
|
||||
operator: SyntaxKind;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
}
|
||||
|
||||
@@ -1646,6 +1646,7 @@ module ts {
|
||||
equals = 0x3D, // =
|
||||
exclamation = 0x21, // !
|
||||
greaterThan = 0x3E, // >
|
||||
hash = 0x23, // #
|
||||
lessThan = 0x3C, // <
|
||||
minus = 0x2D, // -
|
||||
openBrace = 0x7B, // {
|
||||
|
||||
@@ -69,7 +69,7 @@ module ts.BreakpointResolver {
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
if (node.parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node.parent).operator === SyntaxKind.CommaToken) {
|
||||
if (node.parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node.parent).operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
// if this is comma expression, the breakpoint is possible in this expression
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
@@ -93,17 +93,16 @@ module ts.formatting {
|
||||
savedPos = scanner.getStartPos();
|
||||
}
|
||||
|
||||
function shouldRescanGreaterThanToken(container: Node): boolean {
|
||||
if (container.kind !== SyntaxKind.BinaryExpression) {
|
||||
return false;
|
||||
}
|
||||
switch ((<BinaryExpression>container).operator) {
|
||||
case SyntaxKind.GreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanToken:
|
||||
return true;
|
||||
function shouldRescanGreaterThanToken(node: Node): boolean {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.GreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanToken:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -164,7 +163,7 @@ module ts.formatting {
|
||||
|
||||
if (expectedScanAction === ScanAction.RescanGreaterThanToken && currentToken === SyntaxKind.GreaterThanToken) {
|
||||
currentToken = scanner.reScanGreaterToken();
|
||||
Debug.assert((<BinaryExpression>n).operator === currentToken);
|
||||
Debug.assert(n.kind === currentToken);
|
||||
lastScanAction = ScanAction.RescanGreaterThanToken;
|
||||
}
|
||||
else if (expectedScanAction === ScanAction.RescanSlashToken && startsWithSlashToken(currentToken)) {
|
||||
|
||||
@@ -0,0 +1,813 @@
|
||||
module ts {
|
||||
// Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
|
||||
export enum PatternMatchKind {
|
||||
Exact,
|
||||
Prefix,
|
||||
Substring,
|
||||
CamelCase
|
||||
}
|
||||
|
||||
// Information about a match made by the pattern matcher between a candidate and the
|
||||
// search pattern.
|
||||
export interface PatternMatch {
|
||||
// What kind of match this was. Exact matches are better than prefix matches which are
|
||||
// better than substring matches which are better than CamelCase matches.
|
||||
kind: PatternMatchKind;
|
||||
|
||||
// If this was a camel case match, how strong the match is. Higher number means
|
||||
// it was a better match.
|
||||
camelCaseWeight?: number;
|
||||
|
||||
// If this was a match where all constituent parts of the candidate and search pattern
|
||||
// matched case sensitively or case insensitively. Case sensitive matches of the kind
|
||||
// are better matches than insensitive matches.
|
||||
isCaseSensitive: boolean;
|
||||
|
||||
// Whether or not this match occurred with the punctuation from the search pattern stripped
|
||||
// out or not. Matches without the punctuation stripped are better than ones with punctuation
|
||||
// stripped.
|
||||
punctuationStripped: boolean;
|
||||
}
|
||||
|
||||
// The pattern matcher maintains an internal cache of information as it is used. Therefore,
|
||||
// you should not keep it around forever and should get and release the matcher appropriately
|
||||
// once you no longer need it.
|
||||
export interface PatternMatcher {
|
||||
// Used to match a candidate against the last segment of a possibly dotted pattern. This
|
||||
// is useful as a quick check to prevent having to compute a container before calling
|
||||
// "getMatches".
|
||||
//
|
||||
// For example, if the search pattern is "ts.c.SK" and the candidate is "SyntaxKind", then
|
||||
// this will return a successful match, having only tested "SK" against "SyntaxKind". At
|
||||
// that point a call can be made to 'getMatches("SyntaxKind", "ts.compiler")', with the
|
||||
// work to create 'ts.compiler' only being done once the first match succeeded.
|
||||
getMatchesForLastSegmentOfPattern(candidate: string): PatternMatch[];
|
||||
|
||||
// Fully checks a candidate, with an dotted container, against the search pattern.
|
||||
// The candidate must match the last part of the search pattern, and the dotted container
|
||||
// must match the preceding segments of the pattern.
|
||||
getMatches(candidate: string, dottedContainer: string): PatternMatch[];
|
||||
|
||||
// Whether or not the pattern contained dots or not. Clients can use this to determine
|
||||
// If they should call getMatches, or if getMatchesForLastSegmentOfPattern is sufficient.
|
||||
patternContainsDots: boolean;
|
||||
}
|
||||
|
||||
// First we break up the pattern given by dots. Each portion of the pattern between the
|
||||
// dots is a 'Segment'. The 'Segment' contains information about the entire section of
|
||||
// text between the dots, as well as information about any individual 'Words' that we
|
||||
// can break the segment into. A 'Word' is simply a contiguous sequence of characters
|
||||
// that can appear in a typescript identifier. So "GetKeyword" would be one word, while
|
||||
// "Get Keyword" would be two words. Once we have the individual 'words', we break those
|
||||
// into constituent 'character spans' of interest. For example, while 'UIElement' is one
|
||||
// word, it make character spans corresponding to "U", "I" and "Element". These spans
|
||||
// are then used when doing camel cased matches against candidate patterns.
|
||||
interface Segment {
|
||||
// Information about the entire piece of text between the dots. For example, if the
|
||||
// text between the dots is 'GetKeyword', then TotalTextChunk.Text will be 'GetKeyword' and
|
||||
// TotalTextChunk.CharacterSpans will correspond to 'Get', 'Keyword'.
|
||||
totalTextChunk: TextChunk;
|
||||
|
||||
// Information about the subwords compromising the total word. For example, if the
|
||||
// text between the dots is 'GetFoo KeywordBar', then the subwords will be 'GetFoo'
|
||||
// and 'KeywordBar'. Those individual words will have CharacterSpans of ('Get' and
|
||||
// 'Foo') and('Keyword' and 'Bar') respectively.
|
||||
subWordTextChunks: TextChunk[];
|
||||
}
|
||||
|
||||
// Information about a chunk of text from the pattern. The chunk is a piece of text, with
|
||||
// cached information about the character spans within in. Character spans are used for
|
||||
// camel case matching.
|
||||
interface TextChunk {
|
||||
// The text of the chunk. This should be a contiguous sequence of character that could
|
||||
// occur in a symbol name.
|
||||
text: string;
|
||||
|
||||
// The text of a chunk in lower case. Cached because it is needed often to check for
|
||||
// case insensitive matches.
|
||||
textLowerCase: string;
|
||||
|
||||
// Whether or not this chunk is entirely lowercase. We have different rules when searching
|
||||
// for something entirely lowercase or not.
|
||||
isLowerCase: boolean;
|
||||
|
||||
// The spans in this text chunk that we think are of interest and should be matched
|
||||
// independently. For example, if the chunk is for "UIElement" the the spans of interest
|
||||
// correspond to "U", "I" and "Element". If "UIElement" isn't found as an exaxt, prefix.
|
||||
// or substring match, then the character spans will be used to attempt a camel case match.
|
||||
characterSpans: TextSpan[];
|
||||
}
|
||||
|
||||
function createPatternMatch(kind: PatternMatchKind, punctuationStripped: boolean, isCaseSensitive: boolean, camelCaseWeight?: number): PatternMatch {
|
||||
return {
|
||||
kind,
|
||||
punctuationStripped,
|
||||
isCaseSensitive,
|
||||
camelCaseWeight
|
||||
};
|
||||
}
|
||||
|
||||
export function createPatternMatcher(pattern: string): PatternMatcher {
|
||||
// We'll often see the same candidate string many times when searching (For example, when
|
||||
// we see the name of a module that is used everywhere, or the name of an overload). As
|
||||
// such, we cache the information we compute about the candidate for the life of this
|
||||
// pattern matcher so we don't have to compute it multiple times.
|
||||
var stringToWordSpans: Map<TextSpan[]> = {};
|
||||
|
||||
pattern = pattern.trim();
|
||||
|
||||
var fullPatternSegment = createSegment(pattern);
|
||||
var dotSeparatedSegments = pattern.split(".").map(p => createSegment(p.trim()));
|
||||
var invalidPattern = dotSeparatedSegments.length === 0 || forEach(dotSeparatedSegments, segmentIsInvalid);
|
||||
|
||||
return {
|
||||
getMatches,
|
||||
getMatchesForLastSegmentOfPattern,
|
||||
patternContainsDots: dotSeparatedSegments.length > 1
|
||||
};
|
||||
|
||||
// Quick checks so we can bail out when asked to match a candidate.
|
||||
function skipMatch(candidate: string) {
|
||||
return invalidPattern || !candidate;
|
||||
}
|
||||
|
||||
function getMatchesForLastSegmentOfPattern(candidate: string): PatternMatch[] {
|
||||
if (skipMatch(candidate)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return matchSegment(candidate, lastOrUndefined(dotSeparatedSegments));
|
||||
}
|
||||
|
||||
function getMatches(candidate: string, dottedContainer: string): PatternMatch[] {
|
||||
if (skipMatch(candidate)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// First, check that the last part of the dot separated pattern matches the name of the
|
||||
// candidate. If not, then there's no point in proceeding and doing the more
|
||||
// expensive work.
|
||||
var candidateMatch = matchSegment(candidate, lastOrUndefined(dotSeparatedSegments));
|
||||
if (!candidateMatch) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dottedContainer = dottedContainer || "";
|
||||
var containerParts = dottedContainer.split(".");
|
||||
|
||||
// -1 because the last part was checked against the name, and only the rest
|
||||
// of the parts are checked against the container.
|
||||
if (dotSeparatedSegments.length - 1 > containerParts.length) {
|
||||
// There weren't enough container parts to match against the pattern parts.
|
||||
// So this definitely doesn't match.
|
||||
return null;
|
||||
}
|
||||
|
||||
// So far so good. Now break up the container for the candidate and check if all
|
||||
// the dotted parts match up correctly.
|
||||
var totalMatch = candidateMatch;
|
||||
|
||||
for (var i = dotSeparatedSegments.length - 2, j = containerParts.length - 1;
|
||||
i >= 0;
|
||||
i--, j--) {
|
||||
|
||||
var segment = dotSeparatedSegments[i];
|
||||
var containerName = containerParts[j];
|
||||
|
||||
var containerMatch = matchSegment(containerName, segment);
|
||||
if (!containerMatch) {
|
||||
// This container didn't match the pattern piece. So there's no match at all.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addRange(totalMatch, containerMatch);
|
||||
}
|
||||
|
||||
// Success, this symbol's full name matched against the dotted name the user was asking
|
||||
// about.
|
||||
return totalMatch;
|
||||
}
|
||||
|
||||
function getWordSpans(word: string): TextSpan[] {
|
||||
if (!hasProperty(stringToWordSpans, word)) {
|
||||
stringToWordSpans[word] = breakIntoWordSpans(word);
|
||||
}
|
||||
|
||||
return stringToWordSpans[word];
|
||||
}
|
||||
|
||||
function matchTextChunk(candidate: string, chunk: TextChunk, punctuationStripped: boolean): PatternMatch {
|
||||
var index = indexOfIgnoringCase(candidate, chunk.textLowerCase);
|
||||
if (index === 0) {
|
||||
if (chunk.text.length === candidate.length) {
|
||||
// a) Check if the part matches the candidate entirely, in an case insensitive or
|
||||
// sensitive manner. If it does, return that there was an exact match.
|
||||
return createPatternMatch(PatternMatchKind.Exact, punctuationStripped, /*isCaseSensitive:*/ candidate === chunk.text);
|
||||
}
|
||||
else {
|
||||
// b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive
|
||||
// manner. If it does, return that there was a prefix match.
|
||||
return createPatternMatch(PatternMatchKind.Prefix, punctuationStripped, /*isCaseSensitive:*/ startsWith(candidate, chunk.text));
|
||||
}
|
||||
}
|
||||
|
||||
var isLowercase = chunk.isLowerCase;
|
||||
if (isLowercase) {
|
||||
if (index > 0) {
|
||||
// c) If the part is entirely lowercase, then check if it is contained anywhere in the
|
||||
// candidate in a case insensitive manner. If so, return that there was a substring
|
||||
// match.
|
||||
//
|
||||
// Note: We only have a substring match if the lowercase part is prefix match of some
|
||||
// word part. That way we don't match something like 'Class' when the user types 'a'.
|
||||
// But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
|
||||
var wordSpans = getWordSpans(candidate);
|
||||
for (var i = 0, n = wordSpans.length; i < n; i++) {
|
||||
var span = wordSpans[i]
|
||||
if (partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ true)) {
|
||||
return createPatternMatch(PatternMatchKind.Substring, punctuationStripped,
|
||||
/*isCaseSensitive:*/ partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// d) If the part was not entirely lowercase, then check if it is contained in the
|
||||
// candidate in a case *sensitive* manner. If so, return that there was a substring
|
||||
// match.
|
||||
if (candidate.indexOf(chunk.text) > 0) {
|
||||
return createPatternMatch(PatternMatchKind.Substring, punctuationStripped, /*isCaseSensitive:*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLowercase) {
|
||||
// e) If the part was not entirely lowercase, then attempt a camel cased match as well.
|
||||
if (chunk.characterSpans.length > 0) {
|
||||
var candidateParts = getWordSpans(candidate);
|
||||
var camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false);
|
||||
if (camelCaseWeight !== undefined) {
|
||||
return createPatternMatch(PatternMatchKind.CamelCase, punctuationStripped, /*isCaseSensitive:*/ true, /*camelCaseWeight:*/ camelCaseWeight);
|
||||
}
|
||||
|
||||
camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ true);
|
||||
if (camelCaseWeight !== undefined) {
|
||||
return createPatternMatch(PatternMatchKind.CamelCase, punctuationStripped, /*isCaseSensitive:*/ false, /*camelCaseWeight:*/ camelCaseWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isLowercase) {
|
||||
// f) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
|
||||
|
||||
// We could check every character boundary start of the candidate for the pattern. However, that's
|
||||
// an m * n operation in the wost case. Instead, find the first instance of the pattern
|
||||
// substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
|
||||
// filter the list based on a substring that starts on a capital letter and also with a lowercase one.
|
||||
// (Pattern: fogbar, Candidate: quuxfogbarFogBar).
|
||||
if (chunk.text.length < candidate.length) {
|
||||
if (index > 0 && isUpperCaseLetter(candidate.charCodeAt(index))) {
|
||||
return createPatternMatch(PatternMatchKind.Substring, punctuationStripped, /*isCaseSensitive:*/ false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function containsSpaceOrAsterisk(text: string): boolean {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var ch = text.charCodeAt(i);
|
||||
if (ch === CharacterCodes.space || ch === CharacterCodes.asterisk) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function matchSegment(candidate: string, segment: Segment): PatternMatch[] {
|
||||
// First check if the segment matches as is. This is also useful if the segment contains
|
||||
// characters we would normally strip when splitting into parts that we also may want to
|
||||
// match in the candidate. For example if the segment is "@int" and the candidate is
|
||||
// "@int", then that will show up as an exact match here.
|
||||
//
|
||||
// Note: if the segment contains a space or an asterisk then we must assume that it's a
|
||||
// multi-word segment.
|
||||
if (!containsSpaceOrAsterisk(segment.totalTextChunk.text)) {
|
||||
var match = matchTextChunk(candidate, segment.totalTextChunk, /*punctuationStripped:*/ false);
|
||||
if (match) {
|
||||
return [match];
|
||||
}
|
||||
}
|
||||
|
||||
// The logic for pattern matching is now as follows:
|
||||
//
|
||||
// 1) Break the segment passed in into words. Breaking is rather simple and a
|
||||
// good way to think about it that if gives you all the individual alphanumeric words
|
||||
// of the pattern.
|
||||
//
|
||||
// 2) For each word try to match the word against the candidate value.
|
||||
//
|
||||
// 3) Matching is as follows:
|
||||
//
|
||||
// a) Check if the word matches the candidate entirely, in an case insensitive or
|
||||
// sensitive manner. If it does, return that there was an exact match.
|
||||
//
|
||||
// b) Check if the word is a prefix of the candidate, in a case insensitive or
|
||||
// sensitive manner. If it does, return that there was a prefix match.
|
||||
//
|
||||
// c) If the word is entirely lowercase, then check if it is contained anywhere in the
|
||||
// candidate in a case insensitive manner. If so, return that there was a substring
|
||||
// match.
|
||||
//
|
||||
// Note: We only have a substring match if the lowercase part is prefix match of
|
||||
// some word part. That way we don't match something like 'Class' when the user
|
||||
// types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
|
||||
// 'a').
|
||||
//
|
||||
// d) If the word was not entirely lowercase, then check if it is contained in the
|
||||
// candidate in a case *sensitive* manner. If so, return that there was a substring
|
||||
// match.
|
||||
//
|
||||
// e) If the word was not entirely lowercase, then attempt a camel cased match as
|
||||
// well.
|
||||
//
|
||||
// f) The word is all lower case. Is it a case insensitive substring of the candidate starting
|
||||
// on a part boundary of the candidate?
|
||||
//
|
||||
// Only if all words have some sort of match is the pattern considered matched.
|
||||
|
||||
var subWordTextChunks = segment.subWordTextChunks;
|
||||
var matches: PatternMatch[] = undefined;
|
||||
|
||||
for (var i = 0, n = subWordTextChunks.length; i < n; i++) {
|
||||
var subWordTextChunk = subWordTextChunks[i];
|
||||
|
||||
// Try to match the candidate with this word
|
||||
var result = matchTextChunk(candidate, subWordTextChunk, /*punctuationStripped:*/ true);
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
matches = matches || [];
|
||||
matches.push(result);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
function partStartsWith(candidate: string, candidateSpan: TextSpan, pattern: string, ignoreCase: boolean, patternSpan?: TextSpan): boolean {
|
||||
var patternPartStart = patternSpan ? patternSpan.start : 0;
|
||||
var patternPartLength = patternSpan ? patternSpan.length : pattern.length;
|
||||
|
||||
if (patternPartLength > candidateSpan.length) {
|
||||
// Pattern part is longer than the candidate part. There can never be a match.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
for (var i = 0; i < patternPartLength; i++) {
|
||||
var ch1 = pattern.charCodeAt(patternPartStart + i);
|
||||
var ch2 = candidate.charCodeAt(candidateSpan.start + i);
|
||||
if (toLowerCase(ch1) !== toLowerCase(ch2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < patternPartLength; i++) {
|
||||
var ch1 = pattern.charCodeAt(patternPartStart + i);
|
||||
var ch2 = candidate.charCodeAt(candidateSpan.start + i);
|
||||
if (ch1 !== ch2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function tryCamelCaseMatch(candidate: string, candidateParts: TextSpan[], chunk: TextChunk, ignoreCase: boolean): number {
|
||||
var chunkCharacterSpans = chunk.characterSpans;
|
||||
|
||||
// Note: we may have more pattern parts than candidate parts. This is because multiple
|
||||
// pattern parts may match a candidate part. For example "SiUI" against "SimpleUI".
|
||||
// We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI. However, U
|
||||
// and I will both match in UI.
|
||||
|
||||
var currentCandidate = 0;
|
||||
var currentChunkSpan = 0;
|
||||
var firstMatch: number = undefined;
|
||||
var contiguous: boolean = undefined;
|
||||
|
||||
while (true) {
|
||||
// Let's consider our termination cases
|
||||
if (currentChunkSpan === chunkCharacterSpans.length) {
|
||||
// We did match! We shall assign a weight to this
|
||||
var weight = 0;
|
||||
|
||||
// Was this contiguous?
|
||||
if (contiguous) {
|
||||
weight += 1;
|
||||
}
|
||||
|
||||
// Did we start at the beginning of the candidate?
|
||||
if (firstMatch === 0) {
|
||||
weight += 2;
|
||||
}
|
||||
|
||||
return weight;
|
||||
}
|
||||
else if (currentCandidate === candidateParts.length) {
|
||||
// No match, since we still have more of the pattern to hit
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var candidatePart = candidateParts[currentCandidate];
|
||||
var gotOneMatchThisCandidate = false;
|
||||
|
||||
// Consider the case of matching SiUI against SimpleUIElement. The candidate parts
|
||||
// will be Simple/UI/Element, and the pattern parts will be Si/U/I. We'll match 'Si'
|
||||
// against 'Simple' first. Then we'll match 'U' against 'UI'. However, we want to
|
||||
// still keep matching pattern parts against that candidate part.
|
||||
for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) {
|
||||
var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan];
|
||||
|
||||
if (gotOneMatchThisCandidate) {
|
||||
// We've already gotten one pattern part match in this candidate. We will
|
||||
// only continue trying to consumer pattern parts if the last part and this
|
||||
// part are both upper case.
|
||||
if (!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan - 1].start)) ||
|
||||
!isUpperCaseLetter(chunk.text.charCodeAt(chunkCharacterSpans[currentChunkSpan].start))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!partStartsWith(candidate, candidatePart, chunk.text, ignoreCase, chunkCharacterSpan)) {
|
||||
break;
|
||||
}
|
||||
|
||||
gotOneMatchThisCandidate = true;
|
||||
|
||||
firstMatch = firstMatch === undefined ? currentCandidate : firstMatch;
|
||||
|
||||
// If we were contiguous, then keep that value. If we weren't, then keep that
|
||||
// value. If we don't know, then set the value to 'true' as an initial match is
|
||||
// obviously contiguous.
|
||||
contiguous = contiguous === undefined ? true : contiguous;
|
||||
|
||||
candidatePart = createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length);
|
||||
}
|
||||
|
||||
// Check if we matched anything at all. If we didn't, then we need to unset the
|
||||
// contiguous bit if we currently had it set.
|
||||
// If we haven't set the bit yet, then that means we haven't matched anything so
|
||||
// far, and we don't want to change that.
|
||||
if (!gotOneMatchThisCandidate && contiguous !== undefined) {
|
||||
contiguous = false;
|
||||
}
|
||||
|
||||
// Move onto the next candidate.
|
||||
currentCandidate++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to compare two matches to determine which is better. Matches are first
|
||||
// ordered by kind (so all prefix matches always beat all substring matches). Then, if the
|
||||
// match is a camel case match, the relative weights of hte match are used to determine
|
||||
// which is better (with a greater weight being better). Then if the match is of the same
|
||||
// type, then a case sensitive match is considered better than an insensitive one.
|
||||
function patternMatchCompareTo(match1: PatternMatch, match2: PatternMatch): number {
|
||||
return compareType(match1, match2) ||
|
||||
compareCamelCase(match1, match2) ||
|
||||
compareCase(match1, match2) ||
|
||||
comparePunctuation(match1, match2);
|
||||
}
|
||||
|
||||
function comparePunctuation(result1: PatternMatch, result2: PatternMatch) {
|
||||
// Consider a match to be better if it was successful without stripping punctuation
|
||||
// versus a match that had to strip punctuation to succeed.
|
||||
if (result1.punctuationStripped !== result2.punctuationStripped) {
|
||||
return result1.punctuationStripped ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function compareCase(result1: PatternMatch, result2: PatternMatch) {
|
||||
if (result1.isCaseSensitive !== result2.isCaseSensitive) {
|
||||
return result1.isCaseSensitive ? -1 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function compareType(result1: PatternMatch, result2: PatternMatch) {
|
||||
return result1.kind - result2.kind;
|
||||
}
|
||||
|
||||
function compareCamelCase(result1: PatternMatch, result2: PatternMatch) {
|
||||
if (result1.kind === PatternMatchKind.CamelCase && result2.kind === PatternMatchKind.CamelCase) {
|
||||
// Swap the values here. If result1 has a higher weight, then we want it to come
|
||||
// first.
|
||||
return result2.camelCaseWeight - result1.camelCaseWeight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function createSegment(text: string): Segment {
|
||||
return {
|
||||
totalTextChunk: createTextChunk(text),
|
||||
subWordTextChunks: breakPatternIntoTextChunks(text)
|
||||
}
|
||||
}
|
||||
|
||||
// A segment is considered invalid if we couldn't find any words in it.
|
||||
function segmentIsInvalid(segment: Segment) {
|
||||
return segment.subWordTextChunks.length === 0;
|
||||
}
|
||||
|
||||
function isUpperCaseLetter(ch: number) {
|
||||
// Fast check for the ascii range.
|
||||
if (ch >= CharacterCodes.A && ch <= CharacterCodes.Z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ch < CharacterCodes.maxAsciiCharacter || !isUnicodeIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: find a way to determine this for any unicode characters in a
|
||||
// non-allocating manner.
|
||||
var str = String.fromCharCode(ch);
|
||||
return str === str.toUpperCase();
|
||||
}
|
||||
|
||||
function isLowerCaseLetter(ch: number) {
|
||||
// Fast check for the ascii range.
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ch < CharacterCodes.maxAsciiCharacter || !isUnicodeIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// TODO: find a way to determine this for any unicode characters in a
|
||||
// non-allocating manner.
|
||||
var str = String.fromCharCode(ch);
|
||||
return str === str.toLowerCase();
|
||||
}
|
||||
|
||||
function containsUpperCaseLetter(string: string): boolean {
|
||||
for (var i = 0, n = string.length; i < n; i++) {
|
||||
if (isUpperCaseLetter(string.charCodeAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function startsWith(string: string, search: string) {
|
||||
for (var i = 0, n = search.length; i < n; i++) {
|
||||
if (string.charCodeAt(i) !== search.charCodeAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assumes 'value' is already lowercase.
|
||||
function indexOfIgnoringCase(string: string, value: string): number {
|
||||
for (var i = 0, n = string.length - value.length; i <= n; i++) {
|
||||
if (startsWithIgnoringCase(string, value, i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Assumes 'value' is already lowercase.
|
||||
function startsWithIgnoringCase(string: string, value: string, start: number): boolean {
|
||||
for (var i = 0, n = value.length; i < n; i++) {
|
||||
var ch1 = toLowerCase(string.charCodeAt(i + start));
|
||||
var ch2 = value.charCodeAt(i);
|
||||
|
||||
if (ch1 !== ch2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function toLowerCase(ch: number): number {
|
||||
// Fast convert for the ascii range.
|
||||
if (ch >= CharacterCodes.A && ch <= CharacterCodes.Z) {
|
||||
return CharacterCodes.a + (ch - CharacterCodes.A);
|
||||
}
|
||||
|
||||
if (ch < CharacterCodes.maxAsciiCharacter) {
|
||||
return ch;
|
||||
}
|
||||
|
||||
// TODO: find a way to compute this for any unicode characters in a
|
||||
// non-allocating manner.
|
||||
return String.fromCharCode(ch).toLowerCase().charCodeAt(0);
|
||||
}
|
||||
|
||||
function isDigit(ch: number) {
|
||||
// TODO(cyrusn): Find a way to support this for unicode digits.
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
|
||||
}
|
||||
|
||||
function isWordChar(ch: number) {
|
||||
return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === CharacterCodes._ || ch === CharacterCodes.$;
|
||||
}
|
||||
|
||||
function breakPatternIntoTextChunks(pattern: string): TextChunk[] {
|
||||
var result: TextChunk[] = [];
|
||||
var wordStart = 0;
|
||||
var wordLength = 0;
|
||||
|
||||
for (var i = 0; i < pattern.length; i++) {
|
||||
var ch = pattern.charCodeAt(i);
|
||||
if (isWordChar(ch)) {
|
||||
if (wordLength++ === 0) {
|
||||
wordStart = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (wordLength > 0) {
|
||||
result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
|
||||
wordLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wordLength > 0) {
|
||||
result.push(createTextChunk(pattern.substr(wordStart, wordLength)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createTextChunk(text: string): TextChunk {
|
||||
var textLowerCase = text.toLowerCase();
|
||||
return {
|
||||
text,
|
||||
textLowerCase,
|
||||
isLowerCase: text === textLowerCase,
|
||||
characterSpans: breakIntoCharacterSpans(text)
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */ export function breakIntoCharacterSpans(identifier: string): TextSpan[] {
|
||||
return breakIntoSpans(identifier, /*word:*/ false);
|
||||
}
|
||||
|
||||
/* @internal */ export function breakIntoWordSpans(identifier: string): TextSpan[] {
|
||||
return breakIntoSpans(identifier, /*word:*/ true);
|
||||
}
|
||||
|
||||
function breakIntoSpans(identifier: string, word: boolean): TextSpan[] {
|
||||
var result: TextSpan[] = [];
|
||||
|
||||
var wordStart = 0;
|
||||
for (var i = 1, n = identifier.length; i < n; i++) {
|
||||
var lastIsDigit = isDigit(identifier.charCodeAt(i - 1));
|
||||
var currentIsDigit = isDigit(identifier.charCodeAt(i));
|
||||
|
||||
var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i);
|
||||
var hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart);
|
||||
|
||||
if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
|
||||
charIsPunctuation(identifier.charCodeAt(i)) ||
|
||||
lastIsDigit != currentIsDigit ||
|
||||
hasTransitionFromLowerToUpper ||
|
||||
hasTransitionFromUpperToLower) {
|
||||
|
||||
if (!isAllPunctuation(identifier, wordStart, i)) {
|
||||
result.push(createTextSpan(wordStart, i - wordStart));
|
||||
}
|
||||
|
||||
wordStart = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAllPunctuation(identifier, wordStart, identifier.length)) {
|
||||
result.push(createTextSpan(wordStart, identifier.length - wordStart));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function charIsPunctuation(ch: number) {
|
||||
switch (ch) {
|
||||
case CharacterCodes.exclamation:
|
||||
case CharacterCodes.doubleQuote:
|
||||
case CharacterCodes.hash:
|
||||
case CharacterCodes.percent:
|
||||
case CharacterCodes.ampersand:
|
||||
case CharacterCodes.singleQuote:
|
||||
case CharacterCodes.openParen:
|
||||
case CharacterCodes.closeParen:
|
||||
case CharacterCodes.asterisk:
|
||||
case CharacterCodes.comma:
|
||||
case CharacterCodes.minus:
|
||||
case CharacterCodes.dot:
|
||||
case CharacterCodes.slash:
|
||||
case CharacterCodes.colon:
|
||||
case CharacterCodes.semicolon:
|
||||
case CharacterCodes.question:
|
||||
case CharacterCodes.at:
|
||||
case CharacterCodes.openBracket:
|
||||
case CharacterCodes.backslash:
|
||||
case CharacterCodes.closeBracket:
|
||||
case CharacterCodes._:
|
||||
case CharacterCodes.openBrace:
|
||||
case CharacterCodes.closeBrace:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAllPunctuation(identifier: string, start: number, end: number): boolean {
|
||||
for (var i = start; i < end; i++) {
|
||||
var ch = identifier.charCodeAt(i);
|
||||
|
||||
// We don't consider _ or $ as punctuation as there may be things with that name.
|
||||
if (!charIsPunctuation(ch) || ch === CharacterCodes._ || ch === CharacterCodes.$) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function transitionFromUpperToLower(identifier: string, word: boolean, index: number, wordStart: number): boolean {
|
||||
if (word) {
|
||||
// Cases this supports:
|
||||
// 1) IDisposable -> I, Disposable
|
||||
// 2) UIElement -> UI, Element
|
||||
// 3) HTMLDocument -> HTML, Document
|
||||
//
|
||||
// etc.
|
||||
if (index != wordStart &&
|
||||
index + 1 < identifier.length) {
|
||||
var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
|
||||
var nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1));
|
||||
|
||||
if (currentIsUpper && nextIsLower) {
|
||||
// We have a transition from an upper to a lower letter here. But we only
|
||||
// want to break if all the letters that preceded are uppercase. i.e. if we
|
||||
// have "Foo" we don't want to break that into "F, oo". But if we have
|
||||
// "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI,
|
||||
// Foo". i.e. the last uppercase letter belongs to the lowercase letters
|
||||
// that follows. Note: this will make the following not split properly:
|
||||
// "HELLOthere". However, these sorts of names do not show up in .Net
|
||||
// programs.
|
||||
for (var i = wordStart; i < index; i++) {
|
||||
if (!isUpperCaseLetter(identifier.charCodeAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function transitionFromLowerToUpper(identifier: string, word: boolean, index: number): boolean {
|
||||
var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1));
|
||||
var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
|
||||
|
||||
// See if the casing indicates we're starting a new word. Note: if we're breaking on
|
||||
// words, then just seeing an upper case character isn't enough. Instead, it has to
|
||||
// be uppercase and the previous character can't be uppercase.
|
||||
//
|
||||
// For example, breaking "AddMetadata" on words would make: Add Metadata
|
||||
//
|
||||
// on characters would be: A dd M etadata
|
||||
//
|
||||
// Break "AM" on words would be: AM
|
||||
//
|
||||
// on characters would be: A M
|
||||
//
|
||||
// We break the search string on characters. But we break the symbol name on words.
|
||||
var transition = word
|
||||
? (currentIsUpper && !lastIsUpper)
|
||||
: currentIsUpper;
|
||||
return transition;
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
/// <reference path='outliningElementsCollector.ts' />
|
||||
/// <reference path='navigateTo.ts' />
|
||||
/// <reference path='navigationBar.ts' />
|
||||
/// <reference path='patternMatcher.ts' />
|
||||
/// <reference path='signatureHelp.ts' />
|
||||
/// <reference path='utilities.ts' />
|
||||
/// <reference path='formatting\formatting.ts' />
|
||||
/// <reference path='formatting\smartIndenter.ts' />
|
||||
|
||||
module ts {
|
||||
|
||||
export var servicesVersion = "0.4"
|
||||
|
||||
export interface Node {
|
||||
@@ -4648,7 +4648,7 @@ module ts {
|
||||
return true;
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).left === node) {
|
||||
var operator = (<BinaryExpression>parent).operator;
|
||||
var operator = (<BinaryExpression>parent).operatorToken.kind;
|
||||
return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,7 @@ var Board = (function () {
|
||||
function Board() {
|
||||
}
|
||||
Board.prototype.allShipsSunk = function () {
|
||||
return this.ships.every(function (val) {
|
||||
return val.isSunk;
|
||||
});
|
||||
return this.ships.every(function (val) { return val.isSunk; });
|
||||
};
|
||||
return Board;
|
||||
})();
|
||||
|
||||
@@ -527,7 +527,7 @@ declare module "typescript" {
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
left: Expression;
|
||||
operator: SyntaxKind;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
}
|
||||
interface ConditionalExpression extends Expression {
|
||||
@@ -1326,6 +1326,7 @@ declare module "typescript" {
|
||||
equals = 61,
|
||||
exclamation = 33,
|
||||
greaterThan = 62,
|
||||
hash = 35,
|
||||
lessThan = 60,
|
||||
minus = 45,
|
||||
openBrace = 123,
|
||||
@@ -1964,8 +1965,6 @@ function compile(fileNames, options) {
|
||||
}
|
||||
exports.compile = compile;
|
||||
compile(process.argv.slice(2), {
|
||||
noEmitOnError: true,
|
||||
noImplicitAny: true,
|
||||
target: 1 /* ES5 */,
|
||||
module: 1 /* CommonJS */
|
||||
noEmitOnError: true, noImplicitAny: true,
|
||||
target: 1 /* ES5 */, module: 1 /* CommonJS */
|
||||
});
|
||||
|
||||
@@ -1587,9 +1587,9 @@ declare module "typescript" {
|
||||
>left : Expression
|
||||
>Expression : Expression
|
||||
|
||||
operator: SyntaxKind;
|
||||
>operator : SyntaxKind
|
||||
>SyntaxKind : SyntaxKind
|
||||
operatorToken: Node;
|
||||
>operatorToken : Node
|
||||
>Node : Node
|
||||
|
||||
right: Expression;
|
||||
>right : Expression
|
||||
@@ -4190,6 +4190,9 @@ declare module "typescript" {
|
||||
greaterThan = 62,
|
||||
>greaterThan : CharacterCodes
|
||||
|
||||
hash = 35,
|
||||
>hash : CharacterCodes
|
||||
|
||||
lessThan = 60,
|
||||
>lessThan : CharacterCodes
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export function delint(sourceFile: ts.SourceFile) {
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.BinaryExpression:
|
||||
var op = (<ts.BinaryExpression>node).operator;
|
||||
var op = (<ts.BinaryExpression>node).operatorToken.kind;
|
||||
|
||||
if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken) {
|
||||
report(node, "Use '===' and '!=='.")
|
||||
@@ -558,7 +558,7 @@ declare module "typescript" {
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
left: Expression;
|
||||
operator: SyntaxKind;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
}
|
||||
interface ConditionalExpression extends Expression {
|
||||
@@ -1357,6 +1357,7 @@ declare module "typescript" {
|
||||
equals = 61,
|
||||
exclamation = 33,
|
||||
greaterThan = 62,
|
||||
hash = 35,
|
||||
lessThan = 60,
|
||||
minus = 45,
|
||||
openBrace = 123,
|
||||
@@ -1998,12 +1999,13 @@ function delint(sourceFile) {
|
||||
if (ifStatement.thenStatement.kind !== 172 /* Block */) {
|
||||
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
|
||||
}
|
||||
if (ifStatement.elseStatement && ifStatement.elseStatement.kind !== 172 /* Block */ && ifStatement.elseStatement.kind !== 176 /* IfStatement */) {
|
||||
if (ifStatement.elseStatement &&
|
||||
ifStatement.elseStatement.kind !== 172 /* Block */ && ifStatement.elseStatement.kind !== 176 /* IfStatement */) {
|
||||
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
|
||||
}
|
||||
break;
|
||||
case 165 /* BinaryExpression */:
|
||||
var op = node.operator;
|
||||
var op = node.operatorToken.kind;
|
||||
if (op === 28 /* EqualsEqualsToken */ || op === 29 /* ExclamationEqualsToken */) {
|
||||
report(node, "Use '===' and '!=='.");
|
||||
}
|
||||
|
||||
@@ -173,15 +173,17 @@ export function delint(sourceFile: ts.SourceFile) {
|
||||
>SyntaxKind : typeof ts.SyntaxKind
|
||||
>BinaryExpression : ts.SyntaxKind
|
||||
|
||||
var op = (<ts.BinaryExpression>node).operator;
|
||||
var op = (<ts.BinaryExpression>node).operatorToken.kind;
|
||||
>op : ts.SyntaxKind
|
||||
>(<ts.BinaryExpression>node).operator : ts.SyntaxKind
|
||||
>(<ts.BinaryExpression>node).operatorToken.kind : ts.SyntaxKind
|
||||
>(<ts.BinaryExpression>node).operatorToken : ts.Node
|
||||
>(<ts.BinaryExpression>node) : ts.BinaryExpression
|
||||
><ts.BinaryExpression>node : ts.BinaryExpression
|
||||
>ts : unknown
|
||||
>BinaryExpression : ts.BinaryExpression
|
||||
>node : ts.Node
|
||||
>operator : ts.SyntaxKind
|
||||
>operatorToken : ts.Node
|
||||
>kind : ts.SyntaxKind
|
||||
|
||||
if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken) {
|
||||
>op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken : boolean
|
||||
@@ -1731,9 +1733,9 @@ declare module "typescript" {
|
||||
>left : Expression
|
||||
>Expression : Expression
|
||||
|
||||
operator: SyntaxKind;
|
||||
>operator : SyntaxKind
|
||||
>SyntaxKind : SyntaxKind
|
||||
operatorToken: Node;
|
||||
>operatorToken : Node
|
||||
>Node : Node
|
||||
|
||||
right: Expression;
|
||||
>right : Expression
|
||||
@@ -4334,6 +4336,9 @@ declare module "typescript" {
|
||||
greaterThan = 62,
|
||||
>greaterThan : CharacterCodes
|
||||
|
||||
hash = 35,
|
||||
>hash : CharacterCodes
|
||||
|
||||
lessThan = 60,
|
||||
>lessThan : CharacterCodes
|
||||
|
||||
|
||||
@@ -559,7 +559,7 @@ declare module "typescript" {
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
left: Expression;
|
||||
operator: SyntaxKind;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
}
|
||||
interface ConditionalExpression extends Expression {
|
||||
@@ -1358,6 +1358,7 @@ declare module "typescript" {
|
||||
equals = 61,
|
||||
exclamation = 33,
|
||||
greaterThan = 62,
|
||||
hash = 35,
|
||||
lessThan = 60,
|
||||
minus = 45,
|
||||
openBrace = 123,
|
||||
|
||||
@@ -1683,9 +1683,9 @@ declare module "typescript" {
|
||||
>left : Expression
|
||||
>Expression : Expression
|
||||
|
||||
operator: SyntaxKind;
|
||||
>operator : SyntaxKind
|
||||
>SyntaxKind : SyntaxKind
|
||||
operatorToken: Node;
|
||||
>operatorToken : Node
|
||||
>Node : Node
|
||||
|
||||
right: Expression;
|
||||
>right : Expression
|
||||
@@ -4286,6 +4286,9 @@ declare module "typescript" {
|
||||
greaterThan = 62,
|
||||
>greaterThan : CharacterCodes
|
||||
|
||||
hash = 35,
|
||||
>hash : CharacterCodes
|
||||
|
||||
lessThan = 60,
|
||||
>lessThan : CharacterCodes
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@ declare module "typescript" {
|
||||
}
|
||||
interface BinaryExpression extends Expression {
|
||||
left: Expression;
|
||||
operator: SyntaxKind;
|
||||
operatorToken: Node;
|
||||
right: Expression;
|
||||
}
|
||||
interface ConditionalExpression extends Expression {
|
||||
@@ -1395,6 +1395,7 @@ declare module "typescript" {
|
||||
equals = 61,
|
||||
exclamation = 33,
|
||||
greaterThan = 62,
|
||||
hash = 35,
|
||||
lessThan = 60,
|
||||
minus = 45,
|
||||
openBrace = 123,
|
||||
|
||||
@@ -1856,9 +1856,9 @@ declare module "typescript" {
|
||||
>left : Expression
|
||||
>Expression : Expression
|
||||
|
||||
operator: SyntaxKind;
|
||||
>operator : SyntaxKind
|
||||
>SyntaxKind : SyntaxKind
|
||||
operatorToken: Node;
|
||||
>operatorToken : Node
|
||||
>Node : Node
|
||||
|
||||
right: Expression;
|
||||
>right : Expression
|
||||
@@ -4459,6 +4459,9 @@ declare module "typescript" {
|
||||
greaterThan = 62,
|
||||
>greaterThan : CharacterCodes
|
||||
|
||||
hash = 35,
|
||||
>hash : CharacterCodes
|
||||
|
||||
lessThan = 60,
|
||||
>lessThan : CharacterCodes
|
||||
|
||||
|
||||
+1
-3
@@ -19,9 +19,7 @@ module clodule {
|
||||
var clodule = (function () {
|
||||
function clodule() {
|
||||
}
|
||||
clodule.sfn = function (id) {
|
||||
return 42;
|
||||
};
|
||||
clodule.sfn = function (id) { return 42; };
|
||||
return clodule;
|
||||
})();
|
||||
var clodule;
|
||||
|
||||
+4
-12
@@ -28,16 +28,12 @@ var Point = (function () {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
Point.Origin = function () {
|
||||
return { x: 0, y: 0 };
|
||||
}; // unexpected error here bug 840246
|
||||
Point.Origin = function () { return { x: 0, y: 0 }; }; // unexpected error here bug 840246
|
||||
return Point;
|
||||
})();
|
||||
var Point;
|
||||
(function (Point) {
|
||||
function Origin() {
|
||||
return null;
|
||||
}
|
||||
function Origin() { return null; }
|
||||
Point.Origin = Origin; //expected duplicate identifier error
|
||||
})(Point || (Point = {}));
|
||||
var A;
|
||||
@@ -47,17 +43,13 @@ var A;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
Point.Origin = function () {
|
||||
return { x: 0, y: 0 };
|
||||
}; // unexpected error here bug 840246
|
||||
Point.Origin = function () { return { x: 0, y: 0 }; }; // unexpected error here bug 840246
|
||||
return Point;
|
||||
})();
|
||||
A.Point = Point;
|
||||
var Point;
|
||||
(function (Point) {
|
||||
function Origin() {
|
||||
return "";
|
||||
}
|
||||
function Origin() { return ""; }
|
||||
Point.Origin = Origin; //expected duplicate identifier error
|
||||
})(Point = A.Point || (A.Point = {}));
|
||||
})(A || (A = {}));
|
||||
|
||||
+4
-12
@@ -28,16 +28,12 @@ var Point = (function () {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
Point.Origin = function () {
|
||||
return { x: 0, y: 0 };
|
||||
};
|
||||
Point.Origin = function () { return { x: 0, y: 0 }; };
|
||||
return Point;
|
||||
})();
|
||||
var Point;
|
||||
(function (Point) {
|
||||
function Origin() {
|
||||
return "";
|
||||
} // not an error, since not exported
|
||||
function Origin() { return ""; } // not an error, since not exported
|
||||
})(Point || (Point = {}));
|
||||
var A;
|
||||
(function (A) {
|
||||
@@ -46,16 +42,12 @@ var A;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
Point.Origin = function () {
|
||||
return { x: 0, y: 0 };
|
||||
};
|
||||
Point.Origin = function () { return { x: 0, y: 0 }; };
|
||||
return Point;
|
||||
})();
|
||||
A.Point = Point;
|
||||
var Point;
|
||||
(function (Point) {
|
||||
function Origin() {
|
||||
return "";
|
||||
} // not an error since not exported
|
||||
function Origin() { return ""; } // not an error since not exported
|
||||
})(Point = A.Point || (A.Point = {}));
|
||||
})(A || (A = {}));
|
||||
|
||||
@@ -12,6 +12,8 @@ obj[Symbol.foo];
|
||||
|
||||
//// [ES5SymbolProperty1.js]
|
||||
var Symbol;
|
||||
var obj = (_a = {}, _a[Symbol.foo] = 0, _a);
|
||||
var obj = (_a = {}, _a[Symbol.foo] =
|
||||
0,
|
||||
_a);
|
||||
obj[Symbol.foo];
|
||||
var _a;
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
var v = { [yield]: foo }
|
||||
|
||||
//// [FunctionDeclaration8_es6.js]
|
||||
var v = (_a = {}, _a[yield] = foo, _a);
|
||||
var v = (_a = {}, _a[yield] =
|
||||
foo,
|
||||
_a);
|
||||
var _a;
|
||||
|
||||
@@ -5,6 +5,8 @@ function * foo() {
|
||||
|
||||
//// [FunctionDeclaration9_es6.js]
|
||||
function foo() {
|
||||
var v = (_a = {}, _a[] = foo, _a);
|
||||
var v = (_a = {}, _a[] =
|
||||
foo,
|
||||
_a);
|
||||
var _a;
|
||||
}
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
var v = { * }
|
||||
|
||||
//// [FunctionPropertyAssignments4_es6.js]
|
||||
var v = { : function () {
|
||||
} };
|
||||
var v = { : function () { } };
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
var v = { *[foo()]() { } }
|
||||
|
||||
//// [FunctionPropertyAssignments5_es6.js]
|
||||
var v = (_a = {}, _a[foo()] = function () { }, _a);
|
||||
var v = (_a = {}, _a[foo()] = function () { },
|
||||
_a);
|
||||
var _a;
|
||||
|
||||
@@ -7,5 +7,6 @@ var v = { * foo() {
|
||||
|
||||
//// [YieldExpression10_es6.js]
|
||||
var v = { foo: function () {
|
||||
;
|
||||
} };
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,6 +2,4 @@
|
||||
function* foo() { yield }
|
||||
|
||||
//// [YieldExpression13_es6.js]
|
||||
function foo() {
|
||||
;
|
||||
}
|
||||
function foo() { ; }
|
||||
|
||||
@@ -2,6 +2,4 @@
|
||||
var v = { get foo() { yield foo; } }
|
||||
|
||||
//// [YieldExpression17_es6.js]
|
||||
var v = { get foo() {
|
||||
;
|
||||
} };
|
||||
var v = { get foo() { ; } };
|
||||
|
||||
@@ -52,9 +52,7 @@ var C = (function () {
|
||||
}
|
||||
C.privateMethod = function () { };
|
||||
Object.defineProperty(C, "privateGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -65,9 +63,7 @@ var C = (function () {
|
||||
});
|
||||
C.protectedMethod = function () { };
|
||||
Object.defineProperty(C, "protectedGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -78,9 +74,7 @@ var C = (function () {
|
||||
});
|
||||
C.publicMethod = function () { };
|
||||
Object.defineProperty(C, "publicGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -97,9 +91,7 @@ var D = (function () {
|
||||
}
|
||||
D.privateMethod = function () { };
|
||||
Object.defineProperty(D, "privateGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -110,9 +102,7 @@ var D = (function () {
|
||||
});
|
||||
D.protectedMethod = function () { };
|
||||
Object.defineProperty(D, "protectedGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -123,9 +113,7 @@ var D = (function () {
|
||||
});
|
||||
D.publicMethod = function () { };
|
||||
Object.defineProperty(D, "publicGetter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
@@ -142,9 +130,7 @@ var E = (function () {
|
||||
}
|
||||
E.prototype.method = function () { };
|
||||
Object.defineProperty(E.prototype, "getter", {
|
||||
get: function () {
|
||||
return 0;
|
||||
},
|
||||
get: function () { return 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
@@ -47,9 +47,7 @@ var D = (function () {
|
||||
return D;
|
||||
})();
|
||||
var x = {
|
||||
get a() {
|
||||
return 1;
|
||||
}
|
||||
get a() { return 1; }
|
||||
};
|
||||
var y = {
|
||||
set b(v) { }
|
||||
|
||||
@@ -44,9 +44,7 @@ var D = (function () {
|
||||
return D;
|
||||
})();
|
||||
var x = {
|
||||
get a() {
|
||||
return 1;
|
||||
}
|
||||
get a() { return 1; }
|
||||
};
|
||||
var y = {
|
||||
set b(v) { }
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
var v = { get foo() }
|
||||
|
||||
//// [accessorWithoutBody1.js]
|
||||
var v = { get foo() {
|
||||
} };
|
||||
var v = { get foo() { } };
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
var v = { set foo(a) }
|
||||
|
||||
//// [accessorWithoutBody2.js]
|
||||
var v = { set foo(a) {
|
||||
} };
|
||||
var v = { set foo(a) { } };
|
||||
|
||||
@@ -11,14 +11,10 @@ var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
Object.defineProperty(C.prototype, "x", {
|
||||
get: function () {
|
||||
return 1;
|
||||
},
|
||||
get: function () { return 1; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
return C;
|
||||
})();
|
||||
var y = { get foo() {
|
||||
return 3;
|
||||
} };
|
||||
var y = { get foo() { return 3; } };
|
||||
|
||||
@@ -18,38 +18,26 @@ var LanguageSpec_section_4_5_error_cases = (function () {
|
||||
function LanguageSpec_section_4_5_error_cases() {
|
||||
}
|
||||
Object.defineProperty(LanguageSpec_section_4_5_error_cases.prototype, "AnnotatedSetter_SetterFirst", {
|
||||
get: function () {
|
||||
return "";
|
||||
},
|
||||
get: function () { return ""; },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_error_cases.prototype, "AnnotatedSetter_SetterLast", {
|
||||
get: function () {
|
||||
return "";
|
||||
},
|
||||
get: function () { return ""; },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_error_cases.prototype, "AnnotatedGetter_GetterFirst", {
|
||||
get: function () {
|
||||
return "";
|
||||
},
|
||||
set: function (aStr) {
|
||||
aStr = 0;
|
||||
},
|
||||
get: function () { return ""; },
|
||||
set: function (aStr) { aStr = 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_error_cases.prototype, "AnnotatedGetter_GetterLast", {
|
||||
get: function () {
|
||||
return "";
|
||||
},
|
||||
set: function (aStr) {
|
||||
aStr = 0;
|
||||
},
|
||||
get: function () { return ""; },
|
||||
set: function (aStr) { aStr = 0; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
@@ -47,49 +47,37 @@ var LanguageSpec_section_4_5_inference = (function () {
|
||||
function LanguageSpec_section_4_5_inference() {
|
||||
}
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredGetterFromSetterAnnotation", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredGetterFromSetterAnnotation_GetterFirst", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredFromGetter", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredFromGetter_SetterFirst", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredSetterFromGetterAnnotation", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(LanguageSpec_section_4_5_inference.prototype, "InferredSetterFromGetterAnnotation_GetterFirst", {
|
||||
get: function () {
|
||||
return new B();
|
||||
},
|
||||
get: function () { return new B(); },
|
||||
set: function (a) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -84,6 +84,4 @@ var r16 = a + M;
|
||||
var r17 = a + '';
|
||||
var r18 = a + 123;
|
||||
var r19 = a + { a: '' };
|
||||
var r20 = a + (function (a) {
|
||||
return a;
|
||||
});
|
||||
var r20 = a + (function (a) { return a; });
|
||||
|
||||
@@ -25,9 +25,7 @@ var r11 = null + (() => { });
|
||||
|
||||
//// [additionOperatorWithNullValueAndInvalidOperator.js]
|
||||
// If one operand is the null or undefined value, it is treated as having the type of the other operand.
|
||||
function foo() {
|
||||
return undefined;
|
||||
}
|
||||
function foo() { return undefined; }
|
||||
var a;
|
||||
var b;
|
||||
var c;
|
||||
|
||||
@@ -25,9 +25,7 @@ var r11 = undefined + (() => { });
|
||||
|
||||
//// [additionOperatorWithUndefinedValueAndInvalidOperands.js]
|
||||
// If one operand is the null or undefined value, it is treated as having the type of the other operand.
|
||||
function foo() {
|
||||
return undefined;
|
||||
}
|
||||
function foo() { return undefined; }
|
||||
var a;
|
||||
var b;
|
||||
var c;
|
||||
|
||||
@@ -21,9 +21,7 @@ export var a = function () {
|
||||
//// [aliasUsedAsNameValue_0.js]
|
||||
exports.id;
|
||||
//// [aliasUsedAsNameValue_1.js]
|
||||
function b(a) {
|
||||
return null;
|
||||
}
|
||||
function b(a) { return null; }
|
||||
exports.b = b;
|
||||
//// [aliasUsedAsNameValue_2.js]
|
||||
///<reference path='aliasUsedAsNameValue_0.ts' />
|
||||
|
||||
@@ -5,6 +5,4 @@ function foo() { return null; }
|
||||
|
||||
//// [ambientClassOverloadForFunction.js]
|
||||
;
|
||||
function foo() {
|
||||
return null;
|
||||
}
|
||||
function foo() { return null; }
|
||||
|
||||
@@ -6,9 +6,7 @@ var r3 = <<T>(x: T) => T>f; // ambiguous, appears to the parser as a << operatio
|
||||
|
||||
|
||||
//// [ambiguousGenericAssertion1.js]
|
||||
function f(x) {
|
||||
return null;
|
||||
}
|
||||
function f(x) { return null; }
|
||||
var r = function (x) { return x; };
|
||||
var r2 = f; // valid
|
||||
var r3 = << T > (x), T;
|
||||
|
||||
@@ -12,15 +12,11 @@ var x2: string = foof2("s", null);
|
||||
var y2: number = foof2("s", null);
|
||||
|
||||
//// [ambiguousOverload.js]
|
||||
function foof(bar) {
|
||||
return bar;
|
||||
}
|
||||
function foof(bar) { return bar; }
|
||||
;
|
||||
var x = foof("s", null);
|
||||
var y = foof("s", null);
|
||||
function foof2(bar) {
|
||||
return bar;
|
||||
}
|
||||
function foof2(bar) { return bar; }
|
||||
;
|
||||
var x2 = foof2("s", null);
|
||||
var y2 = foof2("s", null);
|
||||
|
||||
@@ -28,6 +28,4 @@ var M;
|
||||
M.C = C;
|
||||
})(M || (M = {}));
|
||||
var c = new M.C();
|
||||
c.m(function (n) {
|
||||
return "hello: " + n;
|
||||
}, 18);
|
||||
c.m(function (n) { return "hello: " + n; }, 18);
|
||||
|
||||
@@ -27,6 +27,4 @@ paired.reduce(function (b1, b2) {
|
||||
}, []);
|
||||
paired.reduce(function (b3, b4) { return b3.concat({}); }, []);
|
||||
paired.map(function (c1) { return c1.count; });
|
||||
paired.map(function (c2) {
|
||||
return c2.count;
|
||||
});
|
||||
paired.map(function (c2) { return c2.count; });
|
||||
|
||||
@@ -95,12 +95,8 @@ var __extends = this.__extends || function (d, b) {
|
||||
var C1 = (function () {
|
||||
function C1() {
|
||||
}
|
||||
C1.prototype.IM1 = function () {
|
||||
return null;
|
||||
};
|
||||
C1.prototype.C1M1 = function () {
|
||||
return null;
|
||||
};
|
||||
C1.prototype.IM1 = function () { return null; };
|
||||
C1.prototype.C1M1 = function () { return null; };
|
||||
return C1;
|
||||
})();
|
||||
var C2 = (function (_super) {
|
||||
@@ -108,17 +104,13 @@ var C2 = (function (_super) {
|
||||
function C2() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
C2.prototype.C2M1 = function () {
|
||||
return null;
|
||||
};
|
||||
C2.prototype.C2M1 = function () { return null; };
|
||||
return C2;
|
||||
})(C1);
|
||||
var C3 = (function () {
|
||||
function C3() {
|
||||
}
|
||||
C3.prototype.CM3M1 = function () {
|
||||
return 3;
|
||||
};
|
||||
C3.prototype.CM3M1 = function () { return 3; };
|
||||
return C3;
|
||||
})();
|
||||
/*
|
||||
@@ -138,9 +130,7 @@ var i1 = c1;
|
||||
var c2 = new C2();
|
||||
var c3 = new C3();
|
||||
var o1 = { one: 1 };
|
||||
var f1 = function () {
|
||||
return new C1();
|
||||
};
|
||||
var f1 = function () { return new C1(); };
|
||||
var arr_any = [];
|
||||
var arr_i1 = [];
|
||||
var arr_c1 = [];
|
||||
|
||||
@@ -69,12 +69,8 @@ var __extends = this.__extends || function (d, b) {
|
||||
var C1 = (function () {
|
||||
function C1() {
|
||||
}
|
||||
C1.prototype.IM1 = function () {
|
||||
return null;
|
||||
};
|
||||
C1.prototype.C1M1 = function () {
|
||||
return null;
|
||||
};
|
||||
C1.prototype.IM1 = function () { return null; };
|
||||
C1.prototype.C1M1 = function () { return null; };
|
||||
return C1;
|
||||
})();
|
||||
var C2 = (function (_super) {
|
||||
@@ -82,17 +78,13 @@ var C2 = (function (_super) {
|
||||
function C2() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
C2.prototype.C2M1 = function () {
|
||||
return null;
|
||||
};
|
||||
C2.prototype.C2M1 = function () { return null; };
|
||||
return C2;
|
||||
})(C1);
|
||||
var C3 = (function () {
|
||||
function C3() {
|
||||
}
|
||||
C3.prototype.CM3M1 = function () {
|
||||
return 3;
|
||||
};
|
||||
C3.prototype.CM3M1 = function () { return 3; };
|
||||
return C3;
|
||||
})();
|
||||
/*
|
||||
@@ -112,9 +104,7 @@ var i1 = c1;
|
||||
var c2 = new C2();
|
||||
var c3 = new C3();
|
||||
var o1 = { one: 1 };
|
||||
var f1 = function () {
|
||||
return new C1();
|
||||
};
|
||||
var f1 = function () { return new C1(); };
|
||||
var arr_any = [];
|
||||
var arr_i1 = [];
|
||||
var arr_c1 = [];
|
||||
@@ -128,9 +118,7 @@ arr_c3 = arr_c2_2; // should be an error - is
|
||||
arr_c3 = arr_c1_2; // should be an error - is
|
||||
arr_c3 = arr_i1_2; // should be an error - is
|
||||
arr_any = f1; // should be an error - is
|
||||
arr_any = function () {
|
||||
return null;
|
||||
}; // should be an error - is
|
||||
arr_any = function () { return null; }; // should be an error - is
|
||||
arr_any = o1; // should be an error - is
|
||||
arr_any = a1; // should be ok - is
|
||||
arr_any = c1; // should be an error - is
|
||||
|
||||
@@ -30,9 +30,7 @@ arr_any = c3; // should be an error - is
|
||||
var C3 = (function () {
|
||||
function C3() {
|
||||
}
|
||||
C3.prototype.CM3M1 = function () {
|
||||
return 3;
|
||||
};
|
||||
C3.prototype.CM3M1 = function () { return 3; };
|
||||
return C3;
|
||||
})();
|
||||
/*
|
||||
@@ -49,7 +47,5 @@ Type 1 of any[]:
|
||||
var c3 = new C3();
|
||||
var o1 = { one: 1 };
|
||||
var arr_any = [];
|
||||
arr_any = function () {
|
||||
return null;
|
||||
}; // should be an error - is
|
||||
arr_any = function () { return null; }; // should be an error - is
|
||||
arr_any = c3; // should be an error - is
|
||||
|
||||
@@ -184,14 +184,10 @@ var M2;
|
||||
// <Identifier>(ParamList) => { ... } is a generic arrow function
|
||||
var generic1 = function (n) { return [n]; };
|
||||
var generic1; // Incorrect error, Bug 829597
|
||||
var generic2 = function (n) {
|
||||
return [n];
|
||||
};
|
||||
var generic2 = function (n) { return [n]; };
|
||||
var generic2;
|
||||
// <Identifier> ((ParamList) => { ... } ) is a type assertion to an arrow function
|
||||
var asserted1 = (function (n) { return [n]; });
|
||||
var asserted1;
|
||||
var asserted2 = (function (n) {
|
||||
return n;
|
||||
});
|
||||
var asserted2 = (function (n) { return n; });
|
||||
var asserted2;
|
||||
|
||||
@@ -91,16 +91,10 @@ function tryCatchFn() {
|
||||
//// [arrowFunctionExpressions.js]
|
||||
// ArrowFormalParameters => AssignmentExpression is equivalent to ArrowFormalParameters => { return AssignmentExpression; }
|
||||
var a = function (p) { return p.length; };
|
||||
var a = function (p) {
|
||||
return p.length;
|
||||
};
|
||||
var a = function (p) { return p.length; };
|
||||
// Identifier => Block is equivalent to(Identifier) => Block
|
||||
var b = function (j) {
|
||||
return 0;
|
||||
};
|
||||
var b = function (j) {
|
||||
return 0;
|
||||
};
|
||||
var b = function (j) { return 0; };
|
||||
var b = function (j) { return 0; };
|
||||
// Identifier => AssignmentExpression is equivalent to(Identifier) => AssignmentExpression
|
||||
var c;
|
||||
var d = function (n) { return c = n; };
|
||||
|
||||
@@ -11,6 +11,4 @@ var C = (function () {
|
||||
}
|
||||
return C;
|
||||
})();
|
||||
var c = new C(function () {
|
||||
return asdf;
|
||||
}); // should error
|
||||
var c = new C(function () { return asdf; }); // should error
|
||||
|
||||
@@ -79,24 +79,12 @@ var missingCurliesWithArrow;
|
||||
(function (missingCurliesWithArrow) {
|
||||
var withStatement;
|
||||
(function (withStatement) {
|
||||
var a = function () {
|
||||
var k = 10;
|
||||
};
|
||||
var b = function () {
|
||||
var k = 10;
|
||||
};
|
||||
var c = function (x) {
|
||||
var k = 10;
|
||||
};
|
||||
var d = function (x, y) {
|
||||
var k = 10;
|
||||
};
|
||||
var e = function (x, y) {
|
||||
var k = 10;
|
||||
};
|
||||
var f = function () {
|
||||
var k = 10;
|
||||
};
|
||||
var a = function () { var k = 10; };
|
||||
var b = function () { var k = 10; };
|
||||
var c = function (x) { var k = 10; };
|
||||
var d = function (x, y) { var k = 10; };
|
||||
var e = function (x, y) { var k = 10; };
|
||||
var f = function () { var k = 10; };
|
||||
})(withStatement || (withStatement = {}));
|
||||
var withoutStatement;
|
||||
(function (withoutStatement) {
|
||||
|
||||
@@ -37,7 +37,9 @@ y
|
||||
//// [asiArith.js]
|
||||
var x = 1;
|
||||
var y = 1;
|
||||
var z = x + + +y;
|
||||
var z = x +
|
||||
+ +y;
|
||||
var a = 1;
|
||||
var b = 1;
|
||||
var c = x - - -y;
|
||||
var c = x -
|
||||
- -y;
|
||||
|
||||
@@ -91,12 +91,8 @@ var h;
|
||||
x = h;
|
||||
var i;
|
||||
x = i;
|
||||
x = { f: function () {
|
||||
return 1;
|
||||
} };
|
||||
x = { f: function (x) {
|
||||
return x;
|
||||
} };
|
||||
x = { f: function () { return 1; } };
|
||||
x = { f: function (x) { return x; } };
|
||||
function j(a) {
|
||||
x = a;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,4 @@ fn(function (a, b) { return true; })
|
||||
//// [assignLambdaToNominalSubtypeOfFunction.js]
|
||||
function fn(cb) { }
|
||||
fn(function (a, b) { return true; });
|
||||
fn(function (a, b) {
|
||||
return true;
|
||||
});
|
||||
fn(function (a, b) { return true; });
|
||||
|
||||
@@ -13,8 +13,6 @@ module M {
|
||||
//// [assignToFn.js]
|
||||
var M;
|
||||
(function (M) {
|
||||
var x = { f: function (n) {
|
||||
return true;
|
||||
} };
|
||||
var x = { f: function (n) { return true; } };
|
||||
x.f = "hello";
|
||||
})(M || (M = {}));
|
||||
|
||||
@@ -44,50 +44,28 @@ b2 = { a: 0 }; // error
|
||||
b2 = { b: 0, a: 0 };
|
||||
var b3;
|
||||
b3 = {
|
||||
f: function (n) {
|
||||
return 0;
|
||||
},
|
||||
g: function (s) {
|
||||
return 0;
|
||||
},
|
||||
f: function (n) { return 0; },
|
||||
g: function (s) { return 0; },
|
||||
m: 0
|
||||
}; // ok
|
||||
b3 = {
|
||||
f: function (n) {
|
||||
return 0;
|
||||
},
|
||||
g: function (s) {
|
||||
return 0;
|
||||
}
|
||||
f: function (n) { return 0; },
|
||||
g: function (s) { return 0; }
|
||||
}; // error
|
||||
b3 = {
|
||||
f: function (n) {
|
||||
return 0;
|
||||
},
|
||||
f: function (n) { return 0; },
|
||||
m: 0
|
||||
}; // error
|
||||
b3 = {
|
||||
f: function (n) {
|
||||
return 0;
|
||||
},
|
||||
g: function (s) {
|
||||
return 0;
|
||||
},
|
||||
f: function (n) { return 0; },
|
||||
g: function (s) { return 0; },
|
||||
m: 0,
|
||||
n: 0,
|
||||
k: function (a) {
|
||||
return null;
|
||||
}
|
||||
k: function (a) { return null; }
|
||||
}; // ok
|
||||
b3 = {
|
||||
f: function (n) {
|
||||
return 0;
|
||||
},
|
||||
g: function (s) {
|
||||
return 0;
|
||||
},
|
||||
f: function (n) { return 0; },
|
||||
g: function (s) { return 0; },
|
||||
n: 0,
|
||||
k: function (a) {
|
||||
return null;
|
||||
}
|
||||
k: function (a) { return null; }
|
||||
}; // error
|
||||
|
||||
@@ -28,12 +28,8 @@ foo(x + y);
|
||||
//// [assignmentCompatBug3.js]
|
||||
function makePoint(x, y) {
|
||||
return {
|
||||
get x() {
|
||||
return x;
|
||||
},
|
||||
get y() {
|
||||
return y;
|
||||
},
|
||||
get x() { return x; },
|
||||
get y() { return y; },
|
||||
//x: "yo",
|
||||
//y: "boo",
|
||||
dist: function () {
|
||||
|
||||
@@ -19,6 +19,4 @@ foo2(["s", "t"]);
|
||||
function foo3(x) { }
|
||||
;
|
||||
foo3(function (s) { });
|
||||
foo3(function (n) {
|
||||
return;
|
||||
});
|
||||
foo3(function (n) { return; });
|
||||
|
||||
@@ -22,9 +22,7 @@ var TokenType;
|
||||
})(TokenType || (TokenType = {}));
|
||||
;
|
||||
var list = {};
|
||||
function returnType() {
|
||||
return null;
|
||||
}
|
||||
function returnType() { return null; }
|
||||
function foo() {
|
||||
var x = returnType();
|
||||
var x = list['one'];
|
||||
|
||||
@@ -57,26 +57,18 @@ a = s;
|
||||
a = a2;
|
||||
t = function (x) { return 1; };
|
||||
t = function () { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = function (x) { return 1; };
|
||||
a = function () { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
var s2;
|
||||
var a3;
|
||||
// these are errors
|
||||
t = s2;
|
||||
t = a3;
|
||||
t = function (x) { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = s2;
|
||||
a = a3;
|
||||
a = function (x) { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
|
||||
@@ -64,38 +64,24 @@ a = s;
|
||||
a = a2;
|
||||
t = { f: function () { return 1; } };
|
||||
t = { f: function (x) { return 1; } };
|
||||
t = { f: function f() {
|
||||
return 1;
|
||||
} };
|
||||
t = { f: function (x) {
|
||||
return '';
|
||||
} };
|
||||
t = { f: function f() { return 1; } };
|
||||
t = { f: function (x) { return ''; } };
|
||||
a = { f: function () { return 1; } };
|
||||
a = { f: function (x) { return 1; } };
|
||||
a = { f: function (x) {
|
||||
return '';
|
||||
} };
|
||||
a = { f: function (x) { return ''; } };
|
||||
// errors
|
||||
t = function () { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = function () { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
var s2;
|
||||
var a3;
|
||||
// these are errors
|
||||
t = s2;
|
||||
t = a3;
|
||||
t = function (x) { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = s2;
|
||||
a = a3;
|
||||
a = function (x) { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
|
||||
@@ -54,12 +54,8 @@ var a3;
|
||||
t = s2;
|
||||
t = a3;
|
||||
t = function (x) { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = s2;
|
||||
a = a3;
|
||||
a = function (x) { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
|
||||
@@ -56,25 +56,17 @@ a = s;
|
||||
a = a2;
|
||||
// errors
|
||||
t = function () { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = function () { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
var s2;
|
||||
var a3;
|
||||
// these are errors
|
||||
t = s2;
|
||||
t = a3;
|
||||
t = function (x) { return 1; };
|
||||
t = function (x) {
|
||||
return '';
|
||||
};
|
||||
t = function (x) { return ''; };
|
||||
a = s2;
|
||||
a = a3;
|
||||
a = function (x) { return 1; };
|
||||
a = function (x) {
|
||||
return '';
|
||||
};
|
||||
a = function (x) { return ''; };
|
||||
|
||||
@@ -31,18 +31,10 @@ var d: new(x: number) => void;
|
||||
d = C; // Error
|
||||
|
||||
//// [assignmentCompatWithOverloads.js]
|
||||
function f1(x) {
|
||||
return null;
|
||||
}
|
||||
function f2(x) {
|
||||
return null;
|
||||
}
|
||||
function f3(x) {
|
||||
return null;
|
||||
}
|
||||
function f4(x) {
|
||||
return undefined;
|
||||
}
|
||||
function f1(x) { return null; }
|
||||
function f2(x) { return null; }
|
||||
function f3(x) { return null; }
|
||||
function f4(x) { return undefined; }
|
||||
var g;
|
||||
g = f1; // OK
|
||||
g = f2; // Error
|
||||
|
||||
@@ -19,9 +19,7 @@ var __test1__;
|
||||
})(__test1__ || (__test1__ = {}));
|
||||
var __test2__;
|
||||
(function (__test2__) {
|
||||
__test2__.obj = function f(a) {
|
||||
return a;
|
||||
};
|
||||
__test2__.obj = function f(a) { return a; };
|
||||
;
|
||||
__test2__.__val__obj = __test2__.obj;
|
||||
})(__test2__ || (__test2__ = {}));
|
||||
|
||||
@@ -84,17 +84,11 @@ var C = (function () {
|
||||
function C() {
|
||||
this = value;
|
||||
}
|
||||
C.prototype.foo = function () {
|
||||
this = value;
|
||||
};
|
||||
C.sfoo = function () {
|
||||
this = value;
|
||||
};
|
||||
C.prototype.foo = function () { this = value; };
|
||||
C.sfoo = function () { this = value; };
|
||||
return C;
|
||||
})();
|
||||
function foo() {
|
||||
this = value;
|
||||
}
|
||||
function foo() { this = value; }
|
||||
this = value;
|
||||
// identifiers: module, class, enum, function
|
||||
var M;
|
||||
@@ -129,12 +123,8 @@ var Derived = (function (_super) {
|
||||
_super.call(this);
|
||||
_super.prototype. = value;
|
||||
}
|
||||
Derived.prototype.foo = function () {
|
||||
_super.prototype. = value;
|
||||
};
|
||||
Derived.sfoo = function () {
|
||||
_super. = value;
|
||||
};
|
||||
Derived.prototype.foo = function () { _super.prototype. = value; };
|
||||
Derived.sfoo = function () { _super. = value; };
|
||||
return Derived;
|
||||
})(C);
|
||||
// function expression
|
||||
|
||||
@@ -26,15 +26,9 @@ var e3 = t3[2]; // any
|
||||
var e4 = t4[3]; // number
|
||||
|
||||
//// [bestCommonTypeOfTuple.js]
|
||||
function f1(x) {
|
||||
return "foo";
|
||||
}
|
||||
function f2(x) {
|
||||
return 10;
|
||||
}
|
||||
function f3(x) {
|
||||
return true;
|
||||
}
|
||||
function f1(x) { return "foo"; }
|
||||
function f2(x) { return 10; }
|
||||
function f3(x) { return true; }
|
||||
var E1;
|
||||
(function (E1) {
|
||||
E1[E1["one"] = 0] = "one";
|
||||
|
||||
@@ -18,9 +18,5 @@ function f() {
|
||||
return b();
|
||||
return d();
|
||||
}
|
||||
function b() {
|
||||
return null;
|
||||
}
|
||||
function d() {
|
||||
return null;
|
||||
}
|
||||
function b() { return null; }
|
||||
function d() { return null; }
|
||||
|
||||
@@ -41,15 +41,11 @@ var ResultIsNumber8 = ~~BOOLEAN;
|
||||
//// [bitwiseNotOperatorWithBooleanType.js]
|
||||
// ~ operator on boolean type
|
||||
var BOOLEAN;
|
||||
function foo() {
|
||||
return true;
|
||||
}
|
||||
function foo() { return true; }
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.foo = function () {
|
||||
return false;
|
||||
};
|
||||
A.foo = function () { return false; };
|
||||
return A;
|
||||
})();
|
||||
var M;
|
||||
|
||||
@@ -48,15 +48,11 @@ var ResultIsNumber13 = ~~~(NUMBER + NUMBER);
|
||||
// ~ operator on number type
|
||||
var NUMBER;
|
||||
var NUMBER1 = [1, 2];
|
||||
function foo() {
|
||||
return 1;
|
||||
}
|
||||
function foo() { return 1; }
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var M;
|
||||
@@ -70,9 +66,7 @@ var ResultIsNumber2 = ~NUMBER1;
|
||||
// number type literal
|
||||
var ResultIsNumber3 = ~1;
|
||||
var ResultIsNumber4 = ~{ x: 1, y: 2 };
|
||||
var ResultIsNumber5 = ~{ x: 1, y: function (n) {
|
||||
return n;
|
||||
} };
|
||||
var ResultIsNumber5 = ~{ x: 1, y: function (n) { return n; } };
|
||||
// number type expressions
|
||||
var ResultIsNumber6 = ~objA.a;
|
||||
var ResultIsNumber7 = ~M.n;
|
||||
|
||||
@@ -47,15 +47,11 @@ var ResultIsNumber14 = ~~~(STRING + STRING);
|
||||
// ~ operator on string type
|
||||
var STRING;
|
||||
var STRING1 = ["", "abc"];
|
||||
function foo() {
|
||||
return "abc";
|
||||
}
|
||||
function foo() { return "abc"; }
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.foo = function () {
|
||||
return "";
|
||||
};
|
||||
A.foo = function () { return ""; };
|
||||
return A;
|
||||
})();
|
||||
var M;
|
||||
@@ -69,9 +65,7 @@ var ResultIsNumber2 = ~STRING1;
|
||||
// string type literal
|
||||
var ResultIsNumber3 = ~"";
|
||||
var ResultIsNumber4 = ~{ x: "", y: "" };
|
||||
var ResultIsNumber5 = ~{ x: "", y: function (s) {
|
||||
return s;
|
||||
} };
|
||||
var ResultIsNumber5 = ~{ x: "", y: function (s) { return s; } };
|
||||
// string type expressions
|
||||
var ResultIsNumber6 = ~objA.a;
|
||||
var ResultIsNumber7 = ~M.n;
|
||||
|
||||
@@ -47,14 +47,10 @@ var r7b = i2.f<number, string, number>(1, '');
|
||||
//// [callGenericFunctionWithIncorrectNumberOfTypeArguments.js]
|
||||
// type parameter lists must exactly match type argument lists
|
||||
// all of these invocations are errors
|
||||
function f(x, y) {
|
||||
return null;
|
||||
}
|
||||
function f(x, y) { return null; }
|
||||
var r1 = f(1, '');
|
||||
var r1b = f(1, '');
|
||||
var f2 = function (x, y) {
|
||||
return null;
|
||||
};
|
||||
var f2 = function (x, y) { return null; };
|
||||
var r2 = f2(1, '');
|
||||
var r2b = f2(1, '');
|
||||
var f3;
|
||||
|
||||
@@ -38,13 +38,9 @@ var r7 = i2.f(1);
|
||||
|
||||
//// [callGenericFunctionWithZeroTypeArguments.js]
|
||||
// valid invocations of generic functions with no explicit type arguments provided
|
||||
function f(x) {
|
||||
return null;
|
||||
}
|
||||
function f(x) { return null; }
|
||||
var r = f(1);
|
||||
var f2 = function (x) {
|
||||
return null;
|
||||
};
|
||||
var f2 = function (x) { return null; };
|
||||
var r2 = f2(1);
|
||||
var f3;
|
||||
var r3 = f3(1);
|
||||
|
||||
@@ -46,13 +46,9 @@ var r8 = a2<number>();
|
||||
//// [callNonGenericFunctionWithTypeArguments.js]
|
||||
// it is always illegal to provide type arguments to a non-generic function
|
||||
// all invocations here are illegal
|
||||
function f(x) {
|
||||
return null;
|
||||
}
|
||||
function f(x) { return null; }
|
||||
var r = f(1);
|
||||
var f2 = function (x) {
|
||||
return null;
|
||||
};
|
||||
var f2 = function (x) { return null; };
|
||||
var r2 = f2(1);
|
||||
var f3;
|
||||
var r3 = f3(1);
|
||||
|
||||
@@ -25,9 +25,7 @@ var Foo = (function () {
|
||||
Foo.prototype.bar1 = function () { };
|
||||
return Foo;
|
||||
})();
|
||||
function F1(a) {
|
||||
return a;
|
||||
}
|
||||
function F1(a) { return a; }
|
||||
var f1 = new Foo("hey");
|
||||
f1.bar1();
|
||||
Foo();
|
||||
|
||||
@@ -33,12 +33,8 @@ var Foo = (function () {
|
||||
Foo.prototype.bar1 = function () { };
|
||||
return Foo;
|
||||
})();
|
||||
function F1(s) {
|
||||
return s;
|
||||
} // error
|
||||
function F1(a) {
|
||||
return a;
|
||||
} // error
|
||||
function F1(s) { return s; } // error
|
||||
function F1(a) { return a; } // error
|
||||
var f1 = new Foo("hey");
|
||||
f1.bar1();
|
||||
Foo();
|
||||
|
||||
@@ -202,9 +202,7 @@ function foo12() {
|
||||
return i2;
|
||||
}
|
||||
var r12 = foo12();
|
||||
function m1() {
|
||||
return 1;
|
||||
}
|
||||
function m1() { return 1; }
|
||||
var m1;
|
||||
(function (m1) {
|
||||
m1.y = 2;
|
||||
|
||||
@@ -21,14 +21,8 @@ var r5b = _.map<number, string>(c2, rf1);
|
||||
//// [callbacksDontShareTypes.js]
|
||||
var _;
|
||||
var c2;
|
||||
var rf1 = function (x) {
|
||||
return x.toFixed();
|
||||
};
|
||||
var r1a = _.map(c2, function (x) {
|
||||
return x.toFixed();
|
||||
});
|
||||
var rf1 = function (x) { return x.toFixed(); };
|
||||
var r1a = _.map(c2, function (x) { return x.toFixed(); });
|
||||
var r1b = _.map(c2, rf1); // this line should not cause the following 2 to have errors
|
||||
var r5a = _.map(c2, function (x) {
|
||||
return x.toFixed();
|
||||
});
|
||||
var r5a = _.map(c2, function (x) { return x.toFixed(); });
|
||||
var r5b = _.map(c2, rf1);
|
||||
|
||||
@@ -47,7 +47,5 @@ var p_cast = ({
|
||||
add: function (dx, dy) {
|
||||
return new Point(this.x + dx, this.y + dy);
|
||||
},
|
||||
mult: function (p) {
|
||||
return p;
|
||||
}
|
||||
mult: function (p) { return p; }
|
||||
});
|
||||
|
||||
@@ -14,6 +14,4 @@ var s3 = s2.each(x => { x.key /* Type is K, should be number */ });
|
||||
//// [chainedSpecializationToObjectTypeLiteral.js]
|
||||
var s;
|
||||
var s2 = s.groupBy(function (s) { return s.length; });
|
||||
var s3 = s2.each(function (x) {
|
||||
x.key; /* Type is K, should be number */
|
||||
});
|
||||
var s3 = s2.each(function (x) { x.key; /* Type is K, should be number */ });
|
||||
|
||||
@@ -20,9 +20,7 @@ var C = (function () {
|
||||
return C;
|
||||
})();
|
||||
var y = {
|
||||
foo: ,
|
||||
class: C2
|
||||
}, _a = void 0;
|
||||
foo: , class: C2 }, _a = void 0;
|
||||
var M;
|
||||
(function (M) {
|
||||
var z = ;
|
||||
|
||||
@@ -19,20 +19,14 @@ var C = (function () {
|
||||
function C() {
|
||||
this.x = 1;
|
||||
}
|
||||
C.prototype.foo = function (x) {
|
||||
return x;
|
||||
};
|
||||
C.prototype.foo = function (x) { return x; };
|
||||
return C;
|
||||
})();
|
||||
var D2 = (function () {
|
||||
function D2() {
|
||||
this.x = 3;
|
||||
}
|
||||
D2.prototype.foo = function (x) {
|
||||
return x;
|
||||
};
|
||||
D2.prototype.other = function (x) {
|
||||
return x;
|
||||
};
|
||||
D2.prototype.foo = function (x) { return x; };
|
||||
D2.prototype.other = function (x) { return x; };
|
||||
return D2;
|
||||
})();
|
||||
|
||||
@@ -23,9 +23,7 @@ var __extends = this.__extends || function (d, b) {
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C = (function () {
|
||||
|
||||
@@ -24,9 +24,7 @@ var __extends = this.__extends || function (d, b) {
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C = (function () {
|
||||
|
||||
@@ -27,9 +27,7 @@ var A = (function () {
|
||||
function A() {
|
||||
this.x = 1;
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C = (function () {
|
||||
|
||||
@@ -28,9 +28,7 @@ var A = (function () {
|
||||
function A() {
|
||||
this.x = 1;
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C = (function () {
|
||||
|
||||
@@ -34,9 +34,7 @@ var A = (function () {
|
||||
A.bar = function () {
|
||||
return "";
|
||||
};
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C = (function () {
|
||||
|
||||
@@ -31,9 +31,7 @@ var A = (function (_super) {
|
||||
function A() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
this.bar();
|
||||
};
|
||||
A.prototype.foo = function () { this.bar(); };
|
||||
return A;
|
||||
})(B);
|
||||
var B = (function () {
|
||||
|
||||
@@ -28,18 +28,14 @@ var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
Object.defineProperty(C.prototype, "y", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
C.prototype.foo = function () { };
|
||||
Object.defineProperty(C, "b", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -28,18 +28,14 @@ var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
Object.defineProperty(C.prototype, "y", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
C.prototype.foo = function () { };
|
||||
Object.defineProperty(C, "b", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -27,18 +27,14 @@ var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
Object.defineProperty(C.prototype, "y", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
C.prototype.foo = function () { };
|
||||
Object.defineProperty(C, "b", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
get: function () { return null; },
|
||||
set: function (x) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -28,9 +28,7 @@ var A = (function () {
|
||||
A.bar = function () {
|
||||
return "";
|
||||
};
|
||||
A.prototype.foo = function () {
|
||||
return 1;
|
||||
};
|
||||
A.prototype.foo = function () { return 1; };
|
||||
return A;
|
||||
})();
|
||||
var C2 = (function (_super) {
|
||||
|
||||
@@ -30,13 +30,9 @@ i = c;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.y = function (a) {
|
||||
return null;
|
||||
};
|
||||
C.prototype.y = function (a) { return null; };
|
||||
Object.defineProperty(C.prototype, "z", {
|
||||
get: function () {
|
||||
return 1;
|
||||
},
|
||||
get: function () { return 1; },
|
||||
set: function (v) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -32,13 +32,9 @@ i = c;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.y = function (a) {
|
||||
return null;
|
||||
};
|
||||
C.prototype.y = function (a) { return null; };
|
||||
Object.defineProperty(C.prototype, "z", {
|
||||
get: function () {
|
||||
return 1;
|
||||
},
|
||||
get: function () { return 1; },
|
||||
set: function (v) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
|
||||
@@ -30,12 +30,8 @@ var C = (function () {
|
||||
this.b = '';
|
||||
this.d = function () { return ''; };
|
||||
}
|
||||
C.prototype.c = function () {
|
||||
return '';
|
||||
};
|
||||
C.f = function () {
|
||||
return '';
|
||||
};
|
||||
C.prototype.c = function () { return ''; };
|
||||
C.f = function () { return ''; };
|
||||
C.g = function () { return ''; };
|
||||
return C;
|
||||
})();
|
||||
|
||||
@@ -41,12 +41,8 @@ var C = (function () {
|
||||
this.b = '';
|
||||
this.d = function () { return ''; };
|
||||
}
|
||||
C.prototype.c = function () {
|
||||
return '';
|
||||
};
|
||||
C.f = function () {
|
||||
return '';
|
||||
};
|
||||
C.prototype.c = function () { return ''; };
|
||||
C.f = function () { return ''; };
|
||||
C.g = function () { return ''; };
|
||||
return C;
|
||||
})();
|
||||
|
||||
@@ -28,12 +28,8 @@ var C = (function () {
|
||||
this.b = '';
|
||||
this.d = function () { return ''; };
|
||||
}
|
||||
C.prototype.c = function () {
|
||||
return '';
|
||||
};
|
||||
C.f = function () {
|
||||
return '';
|
||||
};
|
||||
C.prototype.c = function () { return ''; };
|
||||
C.f = function () { return ''; };
|
||||
C.g = function () { return ''; };
|
||||
return C;
|
||||
})();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user