mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into tsconfig
This commit is contained in:
+38
-12
@@ -3339,6 +3339,8 @@ module ts {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
return isContextSensitiveFunctionLikeDeclaration(<MethodDeclaration>node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return isContextSensitive((<ParenthesizedExpression>node).expression);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -4722,7 +4724,7 @@ module ts {
|
||||
return targetType;
|
||||
}
|
||||
// If current type is a union type, remove all constituents that aren't subtypes of target type
|
||||
if (type.flags && TypeFlags.Union) {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
|
||||
}
|
||||
return type;
|
||||
@@ -5231,6 +5233,8 @@ module ts {
|
||||
case SyntaxKind.TemplateSpan:
|
||||
Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression);
|
||||
return getContextualTypeForSubstitutionExpression(<TemplateExpression>parent.parent, node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return getContextualType(<ParenthesizedExpression>parent);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -6132,8 +6136,10 @@ module ts {
|
||||
var result = candidates;
|
||||
var lastParent: Node;
|
||||
var lastSymbol: Symbol;
|
||||
var cutoffPos: number = 0;
|
||||
var pos: number;
|
||||
var cutoffIndex: number = 0;
|
||||
var index: number;
|
||||
var specializedIndex: number = -1;
|
||||
var spliceIndex: number;
|
||||
Debug.assert(!result.length);
|
||||
for (var i = 0; i < signatures.length; i++) {
|
||||
var signature = signatures[i];
|
||||
@@ -6141,25 +6147,36 @@ module ts {
|
||||
var parent = signature.declaration && signature.declaration.parent;
|
||||
if (!lastSymbol || symbol === lastSymbol) {
|
||||
if (lastParent && parent === lastParent) {
|
||||
pos++;
|
||||
index++;
|
||||
}
|
||||
else {
|
||||
lastParent = parent;
|
||||
pos = cutoffPos;
|
||||
index = cutoffIndex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// current declaration belongs to a different symbol
|
||||
// set cutoffPos so re-orderings in the future won't change result set from 0 to cutoffPos
|
||||
pos = cutoffPos = result.length;
|
||||
// set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
|
||||
index = cutoffIndex = result.length;
|
||||
lastParent = parent;
|
||||
}
|
||||
lastSymbol = symbol;
|
||||
|
||||
for (var j = result.length; j > pos; j--) {
|
||||
result[j] = result[j - 1];
|
||||
// specialized signatures always need to be placed before non-specialized signatures regardless
|
||||
// of the cutoff position; see GH#1133
|
||||
if (signature.hasStringLiterals) {
|
||||
specializedIndex++;
|
||||
spliceIndex = specializedIndex;
|
||||
// The cutoff index always needs to be greater than or equal to the specialized signature index
|
||||
// in order to prevent non-specialized signatures from being added before a specialized
|
||||
// signature.
|
||||
cutoffIndex++;
|
||||
}
|
||||
result[pos] = signature;
|
||||
else {
|
||||
spliceIndex = index;
|
||||
}
|
||||
|
||||
result.splice(spliceIndex, 0, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7191,12 +7208,15 @@ module ts {
|
||||
|
||||
checkVariableLikeDeclaration(node);
|
||||
var func = getContainingFunction(node);
|
||||
if (node.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) {
|
||||
if (node.flags & NodeFlags.AccessibilityModifier) {
|
||||
func = getContainingFunction(node);
|
||||
if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) {
|
||||
error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
|
||||
}
|
||||
}
|
||||
if (node.questionToken && isBindingPattern(node.name) && func.body) {
|
||||
error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
|
||||
}
|
||||
if (node.dotDotDotToken) {
|
||||
if (!isArrayType(getTypeOfSymbol(node.symbol))) {
|
||||
error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type);
|
||||
@@ -7210,17 +7230,20 @@ module ts {
|
||||
checkGrammarIndexSignature(<SignatureDeclaration>node);
|
||||
}
|
||||
// TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled
|
||||
else if (node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ConstructorType ||
|
||||
else if (node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ConstructorType ||
|
||||
node.kind === SyntaxKind.CallSignature || node.kind === SyntaxKind.Constructor ||
|
||||
node.kind === SyntaxKind.ConstructSignature){
|
||||
checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
|
||||
}
|
||||
|
||||
checkTypeParameters(node.typeParameters);
|
||||
|
||||
forEach(node.parameters, checkParameter);
|
||||
|
||||
if (node.type) {
|
||||
checkSourceElement(node.type);
|
||||
}
|
||||
|
||||
if (produceDiagnostics) {
|
||||
checkCollisionWithArgumentsInGeneratedCode(node);
|
||||
if (compilerOptions.noImplicitAny && !node.type) {
|
||||
@@ -10171,6 +10194,9 @@ module ts {
|
||||
else if (node.kind === SyntaxKind.InterfaceDeclaration && flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(lastDeclare, Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare");
|
||||
}
|
||||
else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.AccessibilityModifier) && isBindingPattern((<ParameterDeclaration>node).name)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_a_binding_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
function checkGrammarForDisallowedTrailingComma(list: NodeArray<Node>): boolean {
|
||||
|
||||
@@ -146,6 +146,7 @@ module ts {
|
||||
Modifiers_cannot_appear_here: { code: 1184, category: DiagnosticCategory.Error, key: "Modifiers cannot appear here." },
|
||||
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
|
||||
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
|
||||
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
|
||||
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
||||
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
||||
@@ -297,6 +298,7 @@ module ts {
|
||||
Type_0_has_no_property_1: { code: 2460, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}'." },
|
||||
Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." },
|
||||
A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: DiagnosticCategory.Error, key: "A rest element must be last in an array destructuring pattern" },
|
||||
A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: { code: 2463, category: DiagnosticCategory.Error, key: "A binding pattern parameter cannot be optional in an implementation signature." },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
"A 'declare' modifier cannot be used with an import declaration.": {
|
||||
"category": "Error",
|
||||
"code": 1079,
|
||||
"isEarly": true
|
||||
"isEarly": true
|
||||
},
|
||||
"Invalid 'reference' directive syntax.": {
|
||||
"category": "Error",
|
||||
@@ -659,7 +659,7 @@
|
||||
"An implementation cannot be declared in ambient contexts.": {
|
||||
"category": "Error",
|
||||
"code": 1184,
|
||||
"isEarly": true
|
||||
"isEarly": true
|
||||
},
|
||||
"Modifiers cannot appear here.": {
|
||||
"category": "Error",
|
||||
@@ -673,6 +673,10 @@
|
||||
"category": "Error",
|
||||
"code": 1186
|
||||
},
|
||||
"A parameter property may not be a binding pattern.": {
|
||||
"category": "Error",
|
||||
"code": 1187
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1282,6 +1286,10 @@
|
||||
"category": "Error",
|
||||
"code": 2462
|
||||
},
|
||||
"A binding pattern parameter cannot be optional in an implementation signature.": {
|
||||
"category": "Error",
|
||||
"code": 2463
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -1395,7 +1395,10 @@ module ts {
|
||||
}
|
||||
|
||||
function canFollowModifier(): boolean {
|
||||
return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName();
|
||||
return token === SyntaxKind.OpenBracketToken
|
||||
|| token === SyntaxKind.OpenBraceToken
|
||||
|| token === SyntaxKind.AsteriskToken
|
||||
|| isLiteralPropertyName();
|
||||
}
|
||||
|
||||
// True if positioned at the start of a list element
|
||||
|
||||
@@ -1039,7 +1039,7 @@ module ts {
|
||||
value = 0;
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
return SyntaxKind.NumericLiteral;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
else if (pos + 2 < len && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) {
|
||||
pos += 2;
|
||||
@@ -1049,7 +1049,7 @@ module ts {
|
||||
value = 0;
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
return SyntaxKind.NumericLiteral;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
// Try to parse as an octal
|
||||
if (pos + 1 < len && isOctalDigit(text.charCodeAt(pos + 1))) {
|
||||
|
||||
+19
-9
@@ -810,7 +810,9 @@ module Harness {
|
||||
export function createCompilerHost(inputFiles: { unitName: string; content: string; }[],
|
||||
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
|
||||
scriptTarget: ts.ScriptTarget,
|
||||
useCaseSensitiveFileNames: boolean): ts.CompilerHost {
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory?: string): ts.CompilerHost {
|
||||
|
||||
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
@@ -818,6 +820,8 @@ module Harness {
|
||||
}
|
||||
|
||||
var filemap: { [filename: string]: ts.SourceFile; } = {};
|
||||
var getCurrentDirectory = currentDirectory === undefined ? ts.sys.getCurrentDirectory : () => currentDirectory;
|
||||
|
||||
// Register input files
|
||||
function register(file: { unitName: string; content: string; }) {
|
||||
if (file.content !== undefined) {
|
||||
@@ -828,11 +832,15 @@ module Harness {
|
||||
inputFiles.forEach(register);
|
||||
|
||||
return {
|
||||
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
||||
getCurrentDirectory,
|
||||
getSourceFile: (fn, languageVersion) => {
|
||||
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
|
||||
return filemap[getCanonicalFileName(fn)];
|
||||
}
|
||||
else if (currentDirectory) {
|
||||
var canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
|
||||
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
|
||||
}
|
||||
else if (fn === fourslashFilename) {
|
||||
var tsFn = 'tests/cases/fourslash/' + fourslashFilename;
|
||||
fourslashSourceFile = fourslashSourceFile || ts.createSourceFile(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||
@@ -909,7 +917,9 @@ module Harness {
|
||||
otherFiles: { unitName: string; content: string }[],
|
||||
onComplete: (result: CompilerResult, program: ts.Program) => void,
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions) {
|
||||
options?: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string) {
|
||||
|
||||
options = options || { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
@@ -1063,8 +1073,7 @@ module Harness {
|
||||
var programFiles = inputFiles.map(file => file.unitName);
|
||||
var program = ts.createProgram(programFiles, options, createCompilerHost(inputFiles.concat(otherFiles),
|
||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||
options.target,
|
||||
useCaseSensitiveFileNames));
|
||||
options.target, useCaseSensitiveFileNames, currentDirectory));
|
||||
|
||||
var checker = program.getTypeChecker(/*produceDiagnostics*/ true);
|
||||
|
||||
@@ -1095,7 +1104,9 @@ module Harness {
|
||||
otherFiles: { unitName: string; content: string; }[],
|
||||
result: CompilerResult,
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions) {
|
||||
options?: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string) {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
|
||||
}
|
||||
@@ -1108,9 +1119,8 @@ module Harness {
|
||||
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) {
|
||||
declResult = compileResult;
|
||||
}, settingsCallback, options);
|
||||
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; },
|
||||
settingsCallback, options, currentDirectory);
|
||||
|
||||
return { declInputFiles, declOtherFiles, declResult };
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ var fs: any = require('fs');
|
||||
var path: any = require('path');
|
||||
|
||||
function instrumentForRecording(fn: string, tscPath: string) {
|
||||
instrument(tscPath, 'sys = Playback.wrapSystem(sys); sys.startRecord("' + fn + '");', 'sys.endRecord();');
|
||||
instrument(tscPath, 'ts.sys = Playback.wrapSystem(ts.sys); ts.sys.startRecord("' + fn + '");', 'ts.sys.endRecord();');
|
||||
}
|
||||
|
||||
function instrumentForReplay(logFilename: string, tscPath: string) {
|
||||
instrument(tscPath, 'sys = Playback.wrapSystem(sys); sys.startReplay("' + logFilename + '");');
|
||||
instrument(tscPath, 'ts.sys = Playback.wrapSystem(ts.sys); ts.sys.startReplay("' + logFilename + '");');
|
||||
}
|
||||
|
||||
function instrument(tscPath: string, prepareCode: string, cleanupCode: string = '') {
|
||||
@@ -27,8 +27,12 @@ function instrument(tscPath: string, prepareCode: string, cleanupCode: string =
|
||||
fs.readFile(path.resolve(path.dirname(tscPath) + '/loggedIO.js'), 'utf-8', (err: any, loggerContent: string) => {
|
||||
if (err) throw err;
|
||||
|
||||
var invocationLine = 'ts.executeCommandLine(sys.args);';
|
||||
var invocationLine = 'ts.executeCommandLine(ts.sys.args);';
|
||||
var index1 = tscContent.indexOf(invocationLine);
|
||||
if (index1 < 0) {
|
||||
throw new Error("Could not find " + invocationLine);
|
||||
}
|
||||
|
||||
var index2 = index1 + invocationLine.length;
|
||||
var newContent = tscContent.substr(0, index1) + loggerContent + prepareCode + invocationLine + cleanupCode + tscContent.substr(index2) + '\r\n';
|
||||
fs.writeFile(tscPath, newContent);
|
||||
|
||||
@@ -28,6 +28,7 @@ module RWC {
|
||||
var compilerOptions: ts.CompilerOptions;
|
||||
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
|
||||
var baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
var currentDirectory: string;
|
||||
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
@@ -38,6 +39,7 @@ module RWC {
|
||||
compilerOptions = undefined;
|
||||
baselineOpts = undefined;
|
||||
baseName = undefined;
|
||||
currentDirectory = undefined;
|
||||
});
|
||||
|
||||
it('can compile', () => {
|
||||
@@ -45,6 +47,7 @@ module RWC {
|
||||
var opts: ts.ParsedCommandLine;
|
||||
|
||||
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments);
|
||||
assert.equal(opts.errors.length, 0);
|
||||
@@ -52,7 +55,6 @@ module RWC {
|
||||
|
||||
runWithIOLog(ioLog, () => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
// Load the files
|
||||
ts.forEach(opts.filenames, fileName => {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
@@ -81,7 +83,11 @@ module RWC {
|
||||
// Emit the results
|
||||
compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
|
||||
compilerResult = compileResult;
|
||||
}, /*settingsCallback*/ undefined, opts.options);
|
||||
},
|
||||
/*settingsCallback*/ undefined, opts.options,
|
||||
// Since all Rwc json file specified current directory in its json file, we need to pass this information to compilerHost
|
||||
// so that when the host is asked for current directory, it should give the value from json rather than from process
|
||||
currentDirectory);
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
@@ -145,7 +151,8 @@ module RWC {
|
||||
it('has the expected errors in generated declaration files', () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => {
|
||||
var declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions);
|
||||
var declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
|
||||
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,9 @@ module ts.formatting {
|
||||
|
||||
export function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[] {
|
||||
var line = sourceFile.getLineAndCharacterFromPosition(position).line;
|
||||
Debug.assert(line >= 2);
|
||||
if (line === 1) {
|
||||
return [];
|
||||
}
|
||||
// get the span for the previous\current line
|
||||
var span = {
|
||||
// get start position for the previous line
|
||||
@@ -597,7 +599,11 @@ module ts.formatting {
|
||||
if (listEndToken !== SyntaxKind.Unknown) {
|
||||
if (formattingScanner.isOnToken()) {
|
||||
var tokenInfo = formattingScanner.readTokenInfo(parent);
|
||||
if (tokenInfo.token.kind === listEndToken) {
|
||||
// consume the list end token only if it is still belong to the parent
|
||||
// there might be the case when current token matches end token but does not considered as one
|
||||
// function (x: function) <--
|
||||
// without this check close paren will be interpreted as list end token for function expression which is wrong
|
||||
if (tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
|
||||
// consume list end token
|
||||
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user