Merge branch 'master' into letAndConst

This commit is contained in:
Mohamed Hegazy
2014-10-20 13:34:06 -07:00
113 changed files with 5225 additions and 3436 deletions
+459 -391
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2899,7 +2899,7 @@ module ts {
}
return {
diagnosticMessage: diagnosticMessage,
errorNode: node.parameters[0],
errorNode: <Node>node.parameters[0],
typeName: node.name
};
}
@@ -2920,7 +2920,7 @@ module ts {
}
return {
diagnosticMessage: diagnosticMessage,
errorNode: node.name,
errorNode: <Node>node.name,
typeName: undefined
};
}
+78 -13
View File
@@ -227,6 +227,8 @@ module ts {
return children((<TupleTypeNode>node).elementTypes);
case SyntaxKind.UnionType:
return children((<UnionTypeNode>node).types);
case SyntaxKind.ParenType:
return child((<ParenTypeNode>node).type);
case SyntaxKind.ArrayLiteral:
return children((<ArrayLiteral>node).elements);
case SyntaxKind.ObjectLiteral:
@@ -1078,7 +1080,7 @@ module ts {
return isParameter();
case ParsingContext.TypeArguments:
case ParsingContext.TupleElementTypes:
return isType();
return token === SyntaxKind.CommaToken || isType();
}
Debug.fail("Non-exhaustive case in 'isListElement'.");
@@ -1660,6 +1662,14 @@ module ts {
return finishNode(node);
}
function parseParenType(): ParenTypeNode {
var node = <ParenTypeNode>createNode(SyntaxKind.ParenType);
parseExpected(SyntaxKind.OpenParenToken);
node.type = parseType();
parseExpected(SyntaxKind.CloseParenToken);
return finishNode(node);
}
function parseFunctionType(signatureKind: SyntaxKind): TypeLiteralNode {
var node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
var member = <SignatureDeclaration>createNode(signatureKind);
@@ -1693,10 +1703,7 @@ module ts {
case SyntaxKind.OpenBracketToken:
return parseTupleType();
case SyntaxKind.OpenParenToken:
case SyntaxKind.LessThanToken:
return parseFunctionType(SyntaxKind.CallSignature);
case SyntaxKind.NewKeyword:
return parseFunctionType(SyntaxKind.ConstructSignature);
return parseParenType();
default:
if (isIdentifier()) {
return parseTypeReference();
@@ -1720,18 +1727,18 @@ module ts {
case SyntaxKind.NewKeyword:
return true;
case SyntaxKind.OpenParenToken:
// Only consider an ( as the start of a type if we have () or (id
// We don't want to consider things like (1) as a function type.
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
// or something that starts a type. We don't want to consider things like '(1)' a type.
return lookAhead(() => {
nextToken();
return token === SyntaxKind.CloseParenToken || isParameter();
return token === SyntaxKind.CloseParenToken || isParameter() || isType();
});
default:
return isIdentifier();
}
}
function parseNonUnionType(): TypeNode {
function parsePrimaryType(): TypeNode {
var type = parseNonArrayType();
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
parseExpected(SyntaxKind.CloseBracketToken);
@@ -1742,13 +1749,13 @@ module ts {
return type;
}
function parseType(): TypeNode {
var type = parseNonUnionType();
function parseUnionType(): TypeNode {
var type = parsePrimaryType();
if (token === SyntaxKind.BarToken) {
var types = <NodeArray<TypeNode>>[type];
types.pos = type.pos;
while (parseOptional(SyntaxKind.BarToken)) {
types.push(parseNonUnionType());
types.push(parsePrimaryType());
}
types.end = getNodeEnd();
var node = <UnionTypeNode>createNode(SyntaxKind.UnionType, type.pos);
@@ -1758,6 +1765,48 @@ module ts {
return type;
}
function isFunctionType(): boolean {
return token === SyntaxKind.LessThanToken || token === SyntaxKind.OpenParenToken && lookAhead(() => {
nextToken();
if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) {
// ( )
// ( ...
return true;
}
if (isIdentifier() || isModifier(token)) {
nextToken();
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
isIdentifier() || isModifier(token)) {
// ( id :
// ( id ,
// ( id ?
// ( id =
// ( modifier id
return true;
}
if (token === SyntaxKind.CloseParenToken) {
nextToken();
if (token === SyntaxKind.EqualsGreaterThanToken) {
// ( id ) =>
return true;
}
}
}
return false;
});
}
function parseType(): TypeNode {
if (isFunctionType()) {
return parseFunctionType(SyntaxKind.CallSignature);
}
if (token === SyntaxKind.NewKeyword) {
return parseFunctionType(SyntaxKind.ConstructSignature);
}
return parseUnionType();
}
function parseTypeAnnotation(): TypeNode {
return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined;
}
@@ -2344,13 +2393,29 @@ module ts {
function parseTypeArguments(): NodeArray<TypeNode> {
var typeArgumentListStart = scanner.getTokenPos();
var errorCountBeforeTypeParameterList = file.syntacticErrors.length;
var result = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
// We pass parseSingleTypeArgument instead of parseType as the element parser
// because parseSingleTypeArgument knows how to parse a missing type argument.
// This is useful for signature help. parseType has the disadvantage that when
// it sees a missing type, it changes the LookAheadMode to Error, and the result
// is a broken binary expression, which breaks signature help.
var result = parseBracketedList(ParsingContext.TypeArguments, parseSingleTypeArgument, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
if (!result.length && file.syntacticErrors.length === errorCountBeforeTypeParameterList) {
grammarErrorAtPos(typeArgumentListStart, scanner.getStartPos() - typeArgumentListStart, Diagnostics.Type_argument_list_cannot_be_empty);
}
return result;
}
function parseSingleTypeArgument(): TypeNode {
if (token === SyntaxKind.CommaToken) {
var errorStart = scanner.getTokenPos();
var errorLength = scanner.getTextPos() - errorStart;
grammarErrorAtPos(errorStart, errorLength, Diagnostics.Type_expected);
return createNode(SyntaxKind.Missing);
}
return parseType();
}
function parsePrimaryExpression(): Expression {
switch (token) {
case SyntaxKind.ThisKeyword:
+21 -6
View File
@@ -155,6 +155,7 @@ module ts {
ArrayType,
TupleType,
UnionType,
ParenType,
// Expression
ArrayLiteral,
ObjectLiteral,
@@ -225,7 +226,7 @@ module ts {
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypeReference,
LastTypeNode = UnionType,
LastTypeNode = ParenType,
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
FirstToken = EndOfFileToken,
@@ -345,6 +346,10 @@ module ts {
types: NodeArray<TypeNode>;
}
export interface ParenTypeNode extends TypeNode {
type: TypeNode;
}
export interface StringLiteralTypeNode extends TypeNode {
text: string;
}
@@ -651,18 +656,14 @@ module ts {
getTypeOfNode(node: Node): Type;
getApparentType(type: Type): ApparentType;
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
writeType(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
writeSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
getSymbolDisplayBuilder(): SymbolDisplayBuilder;
getFullyQualifiedName(symbol: Symbol): string;
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
getRootSymbols(symbol: Symbol): Symbol[];
getContextualType(node: Node): Type;
getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
writeSignature(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
writeTypeParameter(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
writeTypeParametersOfSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
isImplementationOfOverload(node: FunctionDeclaration): boolean;
isUndefinedSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
@@ -675,6 +676,18 @@ module ts {
getAliasedSymbol(symbol: Symbol): Symbol;
}
export interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
}
export interface SymbolWriter {
writeKeyword(text: string): void;
writeOperator(text: string): void;
@@ -702,6 +715,7 @@ module ts {
WriteArrowStyleSignature = 0x00000008, // Write arrow style signature
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
InElementType = 0x00000040, // Writing an array or union element type
}
export enum SymbolFormatFlags {
@@ -1017,6 +1031,7 @@ module ts {
export interface InferenceContext {
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
inferUnionTypes: boolean; // Infer union types for disjoint candidates (otherwise undefinedType)
inferenceCount: number; // Incremented for every inference made (whether new or not)
inferences: Type[][]; // Inferences made for each type parameter
inferredTypes: Type[]; // Inferred type for each type parameter
+13 -56
View File
@@ -61,9 +61,11 @@ class CompilerBaselineRunner extends RunnerBase {
var otherFiles: { unitName: string; content: string }[];
var harnessCompiler: Harness.Compiler.HarnessCompiler;
var declToBeCompiled: { unitName: string; content: string }[] = [];
var declOtherFiles: { unitName: string; content: string }[] = [];
var declResult: Harness.Compiler.CompilerResult;
var declFileCompilationResult: {
declInputFiles: { unitName: string; content: string }[];
declOtherFiles: { unitName: string; content: string }[];
declResult: Harness.Compiler.CompilerResult;
};
var createNewInstance = false;
@@ -147,9 +149,7 @@ class CompilerBaselineRunner extends RunnerBase {
toBeCompiled = undefined;
otherFiles = undefined;
harnessCompiler = undefined;
declToBeCompiled = undefined;
declOtherFiles = undefined;
declResult = undefined;
declFileCompilationResult = undefined;
});
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
@@ -173,61 +173,18 @@ class CompilerBaselineRunner extends RunnerBase {
// Source maps?
it('Correct sourcemap content for ' + fileName, () => {
if (result.sourceMapRecord) {
if (options.sourceMap) {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => {
return result.sourceMapRecord;
return result.getSourceMapRecord();
});
}
});
// Compile .d.ts files
it('Correct compiler generated.d.ts for ' + fileName, () => {
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');
}
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
if (Harness.Compiler.isDTS(file.unitName)) {
dtsFiles.push(file);
}
else {
var declFile = findResultCodeFile(file.unitName);
// Look if there is --out file corresponding to this ts file
if (!declFile && options.out) {
declFile = findResultCodeFile(options.out);
if (!declFile || findUnit(declFile.fileName, declToBeCompiled) ||
findUnit(declFile.fileName, declOtherFiles)) {
return;
}
}
if (declFile) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
return;
}
}
function findResultCodeFile(fileName: string) {
return ts.forEach(result.declFilesCode,
declFile => declFile.fileName === (fileName.substr(0, fileName.length - ".ts".length) + ".d.ts")
? declFile : undefined);
}
function findUnit(fileName: string, units: { unitName: string; content: string }[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
}
}
ts.forEach(toBeCompiled, file => addDtsFile(file, declToBeCompiled));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
harnessCompiler.compileFiles(declToBeCompiled, declOtherFiles, function (compileResult) {
declResult = compileResult;
}, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
});
}
declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
}, options);
});
@@ -267,10 +224,10 @@ class CompilerBaselineRunner extends RunnerBase {
}
}
if (declResult && declResult.errors.length) {
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n';
jsCode += '\r\n\r\n';
jsCode += getErrorBaseline(declToBeCompiled, declOtherFiles, declResult);
jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult);
}
if (jsCode.length > 0) {
+86 -13
View File
@@ -139,6 +139,7 @@ module Harness {
deleteFile(filename: string): void;
listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[];
log(text: string): void;
getMemoryUsage? (): number;
}
module IOImpl {
@@ -275,6 +276,13 @@ module Harness {
return filesInFolder(path);
}
export var getMemoryUsage: typeof IO.getMemoryUsage = () => {
if (global.gc) {
global.gc();
}
return process.memoryUsage().heapUsed;
}
}
export module Network {
@@ -806,15 +814,81 @@ module Harness {
});
this.lastErrors = errors;
var result = new CompilerResult(fileOutputs, errors, []);
// Covert the source Map data into the baseline
result.updateSourceMapRecord(program, emitResult ? emitResult.sourceMaps : undefined);
var result = new CompilerResult(fileOutputs, errors, program, sys.getCurrentDirectory(), emitResult ? emitResult.sourceMaps : undefined);
onComplete(result, checker);
// reset what newline means in case the last test changed it
sys.newLine = '\r\n';
return options;
}
public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[],
otherFiles: { unitName: string; content: string; }[],
result: CompilerResult,
settingsCallback?: (settings: ts.CompilerOptions) => void,
options?: ts.CompilerOptions) {
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');
}
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
var declInputFiles: { unitName: string; content: string }[] = [];
var declOtherFiles: { unitName: string; content: string }[] = [];
var declResult: Harness.Compiler.CompilerResult;
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) {
declResult = compileResult;
}, settingsCallback, options);
return { declInputFiles: declInputFiles, declOtherFiles: declOtherFiles, declResult: declResult };
}
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
if (isDTS(file.unitName)) {
dtsFiles.push(file);
}
else if (isTS(file.unitName)) {
var declFile = findResultCodeFile(file.unitName);
if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
}
}
function findResultCodeFile(fileName: string) {
var dTsFileName = ts.forEach(result.program.getSourceFiles(), sourceFile => {
if (sourceFile.filename === fileName) {
// Is this file going to be emitted separately
var sourceFileName: string;
if (ts.isExternalModule(sourceFile) || !options.out) {
if (options.outDir) {
var sourceFilePath = ts.getNormalizedPathFromPathComponents(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram));
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}
else {
sourceFileName = sourceFile.filename;
}
}
else {
// Goes to single --out file
sourceFileName = options.out;
}
return ts.removeFileExtension(sourceFileName) + ".d.ts";
}
});
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
function findUnit(fileName: string, units: { unitName: string; content: string; }[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
}
}
}
}
export function getMinimalDiagnostic(err: ts.Diagnostic): HarnessDiagnostic {
@@ -950,10 +1024,6 @@ module Harness {
}
*/
/** Recreate the harness compiler instance to its default settings */
export function recreate(options?: { useMinimalDefaultLib: boolean; noImplicitAny: boolean; }) {
}
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
var harnessCompiler: HarnessCompiler;
@@ -993,6 +1063,10 @@ module Harness {
return str.substr(str.length - end.length) === end;
}
export function isTS(fileName: string) {
return stringEndsWith(fileName, '.ts');
}
export function isDTS(fileName: string) {
return stringEndsWith(fileName, '.d.ts');
}
@@ -1011,10 +1085,10 @@ module Harness {
public errors: HarnessDiagnostic[] = [];
public declFilesCode: GeneratedFile[] = [];
public sourceMaps: GeneratedFile[] = [];
public sourceMapRecord: string;
/** @param fileResults an array of strings for the fileName and an ITextWriter with its code */
constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], sourceMapRecordLines: string[]) {
constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], public program: ts.Program,
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
var lines: string[] = [];
fileResults.forEach(emittedFile => {
@@ -1032,12 +1106,11 @@ module Harness {
});
this.errors = errors;
this.sourceMapRecord = sourceMapRecordLines.join('\r\n');
}
public updateSourceMapRecord(program: ts.Program, sourceMapData: ts.SourceMapData[]) {
if (sourceMapData) {
this.sourceMapRecord = Harness.SourceMapRecoder.getSourceMapRecord(sourceMapData, program, this.files);
public getSourceMapRecord() {
if (this.sourceMapData) {
return Harness.SourceMapRecoder.getSourceMapRecord(this.sourceMapData, this.program, this.files);
}
}
+10
View File
@@ -419,6 +419,16 @@ class ProjectRunner extends RunnerBase {
// })
//});
}
after(() => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Therefore we have to clean out large objects after the test is done.
nodeCompilerResult = undefined;
amdCompilerResult = undefined;
testCase = undefined;
testFileText = undefined;
testCaseJustName = undefined;
});
});
}
}
+138 -111
View File
@@ -46,144 +46,171 @@ module RWC {
}
export function runRWCTest(jsonPath: string) {
var harnessCompiler = Harness.Compiler.getCompiler();
var opts: ts.ParsedCommandLine;
describe("Testing a RWC project: " + jsonPath, () => {
var inputFiles: { unitName: string; content: string; }[] = [];
var otherFiles: { unitName: string; content: string; }[] = [];
var compilerResult: Harness.Compiler.CompilerResult;
var compilerOptions: ts.CompilerOptions;
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2];
// Compile .d.ts files
var declFileCompilationResult: {
declInputFiles: { unitName: string; content: string }[];
declOtherFiles: { unitName: string; content: string }[];
declResult: Harness.Compiler.CompilerResult;
};
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
var errors = '';
it('has parsable options', () => {
runWithIOLog(ioLog, () => {
opts = ts.parseCommandLine(ioLog.arguments);
assert.equal(opts.errors.length, 0);
});
});
var inputFiles: { unitName: string; content: string; }[] = [];
var otherFiles: { unitName: string; content: string; }[] = [];
var compilerResult: Harness.Compiler.CompilerResult;
it('can compile', () => {
runWithIOLog(ioLog, () => {
harnessCompiler.reset();
// Load the files
ts.forEach(opts.filenames, fileName => {
inputFiles.push(getHarnessCompilerInputUnit(fileName));
});
if (!opts.options.noLib) {
// Find the lib.d.ts file in the input file and add it to the input files list
var libFile = ts.forEach(ioLog.filesRead, fileRead=> Harness.isLibraryFile(fileRead.path) ? fileRead.path : undefined);
if (libFile) {
inputFiles.push(getHarnessCompilerInputUnit(libFile));
}
}
ts.forEach(ioLog.filesRead, fileRead => {
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileRead.path));
var inInputList = ts.forEach(inputFiles, inputFile=> inputFile.unitName === resolvedPath);
if (!inInputList) {
// Add the file to other files
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
});
// do not use lib since we already read it in above
opts.options.noLib = true;
// Emit the results
harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
compilerResult = compileResult;
}, /*settingsCallback*/ undefined, opts.options);
after(() => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Therefore we have to clean out large objects after the test is done.
inputFiles = undefined;
otherFiles = undefined;
compilerResult = undefined;
compilerOptions = undefined;
baselineOpts = undefined;
baseName = undefined;
declFileCompilationResult = undefined;
});
function getHarnessCompilerInputUnit(fileName: string) {
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileName));
try {
var content = sys.readFile(resolvedPath);
it('can compile', () => {
var harnessCompiler = Harness.Compiler.getCompiler();
var opts: ts.ParsedCommandLine;
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
runWithIOLog(ioLog, () => {
opts = ts.parseCommandLine(ioLog.arguments);
assert.equal(opts.errors.length, 0);
});
runWithIOLog(ioLog, () => {
harnessCompiler.reset();
// Load the files
ts.forEach(opts.filenames, fileName => {
inputFiles.push(getHarnessCompilerInputUnit(fileName));
});
if (!opts.options.noLib) {
// Find the lib.d.ts file in the input file and add it to the input files list
var libFile = ts.forEach(ioLog.filesRead, fileRead=> Harness.isLibraryFile(fileRead.path) ? fileRead.path : undefined);
if (libFile) {
inputFiles.push(getHarnessCompilerInputUnit(libFile));
}
}
ts.forEach(ioLog.filesRead, fileRead => {
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileRead.path));
var inInputList = ts.forEach(inputFiles, inputFile=> inputFile.unitName === resolvedPath);
if (!inInputList) {
// Add the file to other files
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
});
// do not use lib since we already read it in above
opts.options.noLib = true;
// Emit the results
compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
compilerResult = compileResult;
}, /*settingsCallback*/ undefined, opts.options);
});
function getHarnessCompilerInputUnit(fileName: string) {
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileName));
try {
var content = sys.readFile(resolvedPath);
}
catch (e) {
// Leave content undefined.
}
return { unitName: resolvedPath, content: content };
}
catch (e) {
// Leave content undefined.
}
return { unitName: resolvedPath, content: content };
}
});
});
// Baselines
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2];
// Baselines
it('Correct compiler generated.d.ts', () => {
declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions);
});
it('has the expected emitted code', () => {
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
return collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s));
}, false, baselineOpts);
});
it('has the expected declaration file content', () => {
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
if (compilerResult.errors.length || !compilerResult.declFilesCode.length) {
return null;
}
return collateOutputs(compilerResult.declFilesCode);
}, false, baselineOpts);
});
it('has the expected source maps', () => {
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
if (!compilerResult.sourceMaps.length) {
return null;
}
return collateOutputs(compilerResult.sourceMaps);
}, false, baselineOpts);
});
it('has correct source map record', () => {
if (compilerResult.sourceMapRecord) {
Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
return compilerResult.sourceMapRecord;
it('has the expected emitted code', () => {
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
return collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s));
}, false, baselineOpts);
}
});
});
it('has the expected errors', () => {
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
if (compilerResult.errors.length === 0) {
return null;
it('has the expected declaration file content', () => {
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
if (compilerResult.errors.length || !compilerResult.declFilesCode.length) {
return null;
}
return collateOutputs(compilerResult.declFilesCode);
}, false, baselineOpts);
});
it('has the expected source maps', () => {
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
if (!compilerResult.sourceMaps.length) {
return null;
}
return collateOutputs(compilerResult.sourceMaps);
}, false, baselineOpts);
});
//it('has correct source map record', () => {
// if (compilerOptions.sourceMap) {
// Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
// return compilerResult.getSourceMapRecord();
// }, false, baselineOpts);
// }
//});
it('has the expected errors', () => {
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
if (compilerResult.errors.length === 0) {
return null;
}
return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors);
}, false, baselineOpts);
});
it('has no errors in generated declaration files', () => {
if (compilerOptions.declaration && !compilerResult.errors.length) {
Harness.Baseline.runBaseline('has no errors in generated declaration files', baseName + '.dts.errors.txt', () => {
if (declFileCompilationResult.declResult.errors.length === 0) {
return null;
}
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
sys.newLine + sys.newLine +
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
}, false, baselineOpts);
}
});
return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors);
}, false, baselineOpts);
// TODO: Type baselines (need to refactor out from compilerRunner)
});
// TODO: Type baselines (need to refactor out from compilerRunner)
}
}
class RWCRunner extends RunnerBase {
private runnerPath = "tests/runners/rwc";
private sourcePath = "tests/cases/rwc/";
private harnessCompiler: Harness.Compiler.HarnessCompiler;
private static sourcePath = "tests/cases/rwc/";
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
public initializeTests(): void {
// Recreate the compiler with the default lib
Harness.Compiler.recreate({ useMinimalDefaultLib: false, noImplicitAny: false });
this.harnessCompiler = Harness.Compiler.getCompiler();
// Read in and evaluate the test list
var testList = Harness.IO.listFiles(this.sourcePath, /.+\.json$/);
var testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
for (var i = 0; i < testList.length; i++) {
this.runTest(testList[i]);
}
}
private runTest(jsonFilename: string) {
describe("Testing a RWC project: " + jsonFilename, () => {
RWC.runRWCTest(jsonFilename);
});
RWC.runRWCTest(jsonFilename);
}
}
+22 -9
View File
@@ -1462,7 +1462,7 @@ module ts {
}
}
function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] {
export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] {
writeDisplayParts(displayPartWriter);
var result = displayPartWriter.displayParts();
displayPartWriter.clear();
@@ -1471,19 +1471,19 @@ module ts {
export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] {
return mapToDisplayParts(writer => {
typechecker.writeType(type, writer, enclosingDeclaration, flags);
typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
});
}
export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[] {
return mapToDisplayParts(writer => {
typeChecker.writeSymbol(symbol, writer, enclosingDeclaration, meaning, flags);
typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags);
});
}
function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[]{
return mapToDisplayParts(writer => {
typechecker.writeSignature(signature, writer, enclosingDeclaration, flags);
typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
});
}
@@ -2694,7 +2694,7 @@ module ts {
// TODO(drosen): use contextual SemanticMeaning.
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker): string {
var flags = typeInfoResolver.getRootSymbols(symbol)[0].getFlags();
var flags = symbol.getFlags();
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement;
@@ -2734,6 +2734,18 @@ module ts {
if (flags & SymbolFlags.Property) return ScriptElementKind.memberVariableElement;
if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
if (flags & SymbolFlags.UnionProperty) {
return forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => {
var rootSymbolFlags = rootSymbol.getFlags();
if (rootSymbolFlags & SymbolFlags.Property) {
return ScriptElementKind.memberVariableElement;
}
if (rootSymbolFlags & SymbolFlags.GetAccessor) return ScriptElementKind.memberVariableElement;
if (rootSymbolFlags & SymbolFlags.SetAccessor) return ScriptElementKind.memberVariableElement;
Debug.assert(rootSymbolFlags & SymbolFlags.Method);
}) || ScriptElementKind.memberFunctionElement;
}
return ScriptElementKind.unknown;
}
@@ -2785,7 +2797,7 @@ module ts {
semanticMeaning = getMeaningFromLocation(location)) {
var displayParts: SymbolDisplayPart[] = [];
var documentation: SymbolDisplayPart[];
var symbolFlags = typeResolver.getRootSymbols(symbol)[0].flags;
var symbolFlags = symbol.flags;
var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver);
var hasAddedSymbolInfo: boolean;
// Class at constructor site need to be shown as constructor apart from property,method, vars
@@ -3001,7 +3013,7 @@ module ts {
// If the type is type parameter, format it specially
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) {
var typeParameterParts = mapToDisplayParts(writer => {
typeResolver.writeTypeParameter(<TypeParameter>type, writer, enclosingDeclaration);
typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(<TypeParameter>type, writer, enclosingDeclaration);
});
displayParts.push.apply(displayParts, typeParameterParts);
}
@@ -3013,7 +3025,8 @@ module ts {
symbolFlags & SymbolFlags.Method ||
symbolFlags & SymbolFlags.Constructor ||
symbolFlags & SymbolFlags.Signature ||
symbolFlags & SymbolFlags.Accessor) {
symbolFlags & SymbolFlags.Accessor ||
symbolKind === ScriptElementKind.memberFunctionElement) {
var allSignatures = type.getCallSignatures();
addSignatureDisplayParts(allSignatures[0], allSignatures);
}
@@ -3069,7 +3082,7 @@ module ts {
function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) {
var typeParameterParts = mapToDisplayParts(writer => {
typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration);
typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
});
displayParts.push.apply(displayParts, typeParameterParts);
}
+68 -64
View File
@@ -258,6 +258,13 @@ module ts.SignatureHelp {
return undefined;
}
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
var children = parent.getChildren(sourceFile);
var indexOfOpenerToken = children.indexOf(openerToken);
Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
return children[indexOfOpenerToken + 1];
}
/**
* The selectedItemIndex could be negative for several reasons.
* 1. There are too many arguments for all of the overloads
@@ -287,74 +294,51 @@ module ts.SignatureHelp {
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems {
var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list;
var parent = <CallExpression>argumentListOrTypeArgumentList.parent;
var isTypeParameterHelp = parent.typeArguments && parent.typeArguments.pos === argumentListOrTypeArgumentList.pos;
Debug.assert(isTypeParameterHelp || parent.arguments.pos === argumentListOrTypeArgumentList.pos);
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
var parameters = candidateSignature.parameters;
var parameterHelpItems: SignatureHelpParameter[] = parameters.length === 0 ? emptyArray : map(parameters, p => {
var displayParts: SymbolDisplayPart[] = [];
var signatureHelpParameters: SignatureHelpParameter[];
var prefixParts: SymbolDisplayPart[] = [];
var suffixParts: SymbolDisplayPart[] = [];
if (candidateSignature.hasRestParameter && parameters[parameters.length - 1] === p) {
displayParts.push(punctuationPart(SyntaxKind.DotDotDotToken));
}
displayParts.push(symbolPart(p.name, p));
var isOptional = !!(p.valueDeclaration.flags & NodeFlags.QuestionMark);
if (isOptional) {
displayParts.push(punctuationPart(SyntaxKind.QuestionToken));
}
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
displayParts.push(spacePart());
var typeParts = typeToDisplayParts(typeInfoResolver, typeInfoResolver.getTypeOfSymbol(p), argumentListOrTypeArgumentList);
displayParts.push.apply(displayParts, typeParts);
return {
name: p.name,
documentation: p.getDocumentationComment(),
displayParts: displayParts,
isOptional: isOptional
};
});
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
var prefixParts = callTargetSymbol ? symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : [];
var separatorParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()];
// TODO(jfreeman): Constraints?
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
for (var i = 0, n = candidateSignature.typeParameters.length; i < n; i++) {
if (i) {
prefixParts.push.apply(prefixParts, separatorParts);
}
var tp = candidateSignature.typeParameters[i].symbol;
prefixParts.push(symbolPart(tp.name, tp));
}
prefixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
if (callTargetDisplayParts) {
prefixParts.push.apply(prefixParts, callTargetDisplayParts);
}
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
if (isTypeParameterHelp) {
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
var typeParameters = candidateSignature.typeParameters;
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
suffixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
var parameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, argumentListOrTypeArgumentList));
suffixParts.push.apply(suffixParts, parameterParts);
}
else {
var typeParameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList));
prefixParts.push.apply(prefixParts, typeParameterParts);
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
var parameters = candidateSignature.parameters;
signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
suffixParts.push(punctuationPart(SyntaxKind.CloseParenToken));
}
var suffixParts = [punctuationPart(SyntaxKind.CloseParenToken)];
suffixParts.push(punctuationPart(SyntaxKind.ColonToken));
suffixParts.push(spacePart());
var typeParts = typeToDisplayParts(typeInfoResolver, candidateSignature.getReturnType(), argumentListOrTypeArgumentList);
suffixParts.push.apply(suffixParts, typeParts);
var returnTypeParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, argumentListOrTypeArgumentList));
suffixParts.push.apply(suffixParts, returnTypeParts);
return {
isVariadic: candidateSignature.hasRestParameter,
prefixDisplayParts: prefixParts,
suffixDisplayParts: suffixParts,
separatorDisplayParts: separatorParts,
parameters: parameterHelpItems,
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
parameters: signatureHelpParameters,
documentation: candidateSignature.getDocumentationComment()
};
});
@@ -400,12 +384,32 @@ module ts.SignatureHelp {
argumentIndex: argumentIndex,
argumentCount: argumentCount
};
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
var displayParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, argumentListOrTypeArgumentList));
var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark);
return {
name: parameter.name,
documentation: parameter.getDocumentationComment(),
displayParts: displayParts,
isOptional: isOptional
};
}
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
var displayParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, argumentListOrTypeArgumentList));
return {
name: typeParameter.symbol.name,
documentation: emptyArray,
displayParts: displayParts,
isOptional: false
};
}
}
}
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
var children = parent.getChildren(sourceFile);
var indexOfOpenerToken = children.indexOf(openerToken);
return children[indexOfOpenerToken + 1];
}
}