merge with origin/release-2.0.5

This commit is contained in:
Vladimir Matveev
2016-09-13 15:59:04 -07:00
189 changed files with 2854 additions and 1443 deletions
+81 -20
View File
@@ -2,6 +2,8 @@
/* @internal */
namespace ts {
const ambientModuleSymbolRegex = /^".+"$/;
let nextSymbolId = 1;
let nextNodeId = 1;
let nextMergeId = 1;
@@ -100,6 +102,7 @@ namespace ts {
getAliasedSymbol: resolveAlias,
getEmitResolver,
getExportsOfModule: getExportsOfModuleAsArray,
getAmbientModules,
getJsxElementAttributesType,
getJsxIntrinsicTagNames,
@@ -329,6 +332,7 @@ namespace ts {
const assignableRelation = createMap<RelationComparisonResult>();
const comparableRelation = createMap<RelationComparisonResult>();
const identityRelation = createMap<RelationComparisonResult>();
const enumRelation = createMap<boolean>();
// This is for caching the result of getSymbolDisplayBuilder. Do not access directly.
let _displayBuilder: SymbolDisplayBuilder;
@@ -3347,7 +3351,13 @@ namespace ts {
// Otherwise, fall back to 'any'.
else {
if (compilerOptions.noImplicitAny) {
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation, symbolToString(symbol));
if (setter) {
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
}
else {
Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
error(getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
}
}
type = anyType;
}
@@ -6186,8 +6196,14 @@ namespace ts {
if (source === target) {
return true;
}
if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum)) {
return false;
const id = source.id + "," + target.id;
if (enumRelation[id] !== undefined) {
return enumRelation[id];
}
if (source.symbol.name !== target.symbol.name ||
!(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum) ||
(source.flags & TypeFlags.Union) !== (target.flags & TypeFlags.Union)) {
return enumRelation[id] = false;
}
const targetEnumType = getTypeOfSymbol(target.symbol);
for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) {
@@ -6198,11 +6214,11 @@ namespace ts {
errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name,
typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType));
}
return false;
return enumRelation[id] = false;
}
}
}
return true;
return enumRelation[id] = true;
}
function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorReporter?: ErrorReporter) {
@@ -6217,8 +6233,18 @@ namespace ts {
if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true;
if (relation === assignableRelation || relation === comparableRelation) {
if (source.flags & TypeFlags.Any) return true;
if (source.flags & (TypeFlags.Number | TypeFlags.NumberLiteral) && target.flags & TypeFlags.Enum) return true;
if (source.flags & TypeFlags.NumberLiteral && target.flags & TypeFlags.EnumLiteral && (<LiteralType>source).text === (<LiteralType>target).text) return true;
if ((source.flags & TypeFlags.Number | source.flags & TypeFlags.NumberLiteral) && target.flags & TypeFlags.EnumLike) return true;
if (source.flags & TypeFlags.EnumLiteral &&
target.flags & TypeFlags.EnumLiteral &&
(<LiteralType>source).text === (<LiteralType>target).text &&
isEnumTypeRelatedTo((<EnumLiteralType>source).baseType, (<EnumLiteralType>target).baseType, errorReporter)) {
return true;
}
if (source.flags & TypeFlags.EnumLiteral &&
target.flags & TypeFlags.Enum &&
isEnumTypeRelatedTo(<EnumType>target, (<EnumLiteralType>source).baseType, errorReporter)) {
return true;
}
}
return false;
}
@@ -11961,18 +11987,12 @@ namespace ts {
// Function interface, since they have none by default. This is a bit of a leap of faith
// that the user will not add any.
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
// TS 1.0 spec: 4.12
// If FuncExpr is of type Any, or of an object type that has no call or construct signatures
// but is a subtype of the Function interface, the call is an untyped function call. In an
// untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
// TS 1.0 Spec: 4.12
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
// types are provided for the argument expressions, and the result is always of type Any.
// We exclude union types because we may have a union of function types that happen to have
// no common signatures.
if (isTypeAny(funcType) ||
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
// The unknownType indicates that an error already occurred (and was reported). No
// need to report another error in this case.
if (funcType !== unknownType && node.typeArguments) {
@@ -11995,6 +12015,29 @@ namespace ts {
return resolveCall(node, callSignatures, candidatesOutArray);
}
/**
* TS 1.0 spec: 4.12
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
* but is a subtype of the Function interface, the call is an untyped function call.
*/
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
if (isTypeAny(funcType)) {
return true;
}
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
return true;
}
if (!numCallSignatures && !numConstructSignatures) {
// We exclude union types because we may have a union of function types that happen to have
// no common signatures.
if (funcType.flags & TypeFlags.Union) {
return false;
}
return isTypeAssignableTo(funcType, globalFunctionType);
}
return false;
}
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
if (node.arguments && languageVersion < ScriptTarget.ES5) {
const spreadIndex = getSpreadArgumentIndex(node.arguments);
@@ -12120,8 +12163,9 @@ namespace ts {
}
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
return resolveUntypedCall(node);
}
@@ -12166,7 +12210,8 @@ namespace ts {
}
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
return resolveUntypedCall(node);
}
@@ -18767,7 +18812,13 @@ namespace ts {
(augmentations || (augmentations = [])).push(file.moduleAugmentations);
}
if (file.symbol && file.symbol.globalExports) {
mergeSymbolTable(globals, file.symbol.globalExports);
// Merge in UMD exports with first-in-wins semantics (see #9771)
const source = file.symbol.globalExports;
for (const id in source) {
if (!(id in globals)) {
globals[id] = source[id];
}
}
}
});
@@ -19992,5 +20043,15 @@ namespace ts {
return true;
}
}
function getAmbientModules(): Symbol[] {
const result: Symbol[] = [];
for (const sym in globals) {
if (ambientModuleSymbolRegex.test(sym)) {
result.push(globals[sym]);
}
}
return result;
}
}
}
+9 -5
View File
@@ -2875,11 +2875,7 @@
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
"category": "Error",
"code": 7015
},
"Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation.": {
"category": "Error",
"code": 7016
},
},
"Index signature of object type implicitly has an 'any' type.": {
"category": "Error",
"code": 7017
@@ -2936,6 +2932,14 @@
"category": "Error",
"code": 7031
},
"Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.": {
"category": "Error",
"code": 7032
},
"Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.": {
"category": "Error",
"code": 7033
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
+1 -1
View File
@@ -6587,7 +6587,7 @@ const _super = (function (geti, seti) {
// import { x, y } from "foo"
// import d, * as x from "foo"
// import d, { x, y } from "foo"
const isNakedImport = SyntaxKind.ImportDeclaration && !(<ImportDeclaration>node).importClause;
const isNakedImport = node.kind === SyntaxKind.ImportDeclaration && !(<ImportDeclaration>node).importClause;
if (!isNakedImport) {
write(varOrConst);
write(getGeneratedNameForNode(<ImportDeclaration>node));
+1
View File
@@ -2340,6 +2340,7 @@ namespace ts {
token() === SyntaxKind.LessThanToken ||
token() === SyntaxKind.QuestionToken ||
token() === SyntaxKind.ColonToken ||
token() === SyntaxKind.CommaToken ||
canParseSemicolon();
}
return false;
+6 -9
View File
@@ -11,9 +11,9 @@ namespace ts {
const defaultTypeRoots = ["node_modules/@types"];
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string {
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
while (true) {
const fileName = combinePaths(searchPath, "tsconfig.json");
const fileName = combinePaths(searchPath, configName);
if (fileExists(fileName)) {
return fileName;
}
@@ -79,22 +79,19 @@ namespace ts {
const typeReferenceExtensions = [".d.ts"];
function getEffectiveTypeRoots(options: CompilerOptions, host: ModuleResolutionHost) {
export function getEffectiveTypeRoots(options: CompilerOptions, currentDirectory: string) {
if (options.typeRoots) {
return options.typeRoots;
}
let currentDirectory: string;
if (options.configFilePath) {
currentDirectory = getDirectoryPath(options.configFilePath);
}
else if (host.getCurrentDirectory) {
currentDirectory = host.getCurrentDirectory();
}
if (!currentDirectory) {
return undefined;
}
return map(defaultTypeRoots, d => combinePaths(currentDirectory, d));
}
@@ -112,7 +109,7 @@ namespace ts {
traceEnabled
};
const typeRoots = getEffectiveTypeRoots(options, host);
const typeRoots = getEffectiveTypeRoots(options, host.getCurrentDirectory && host.getCurrentDirectory());
if (traceEnabled) {
if (containingFile === undefined) {
if (typeRoots === undefined) {
@@ -427,7 +424,7 @@ namespace ts {
// Walk the primary type lookup locations
const result: string[] = [];
if (host.directoryExists && host.getDirectories) {
const typeRoots = getEffectiveTypeRoots(options, host);
const typeRoots = getEffectiveTypeRoots(options, host.getCurrentDirectory && host.getCurrentDirectory());
if (typeRoots) {
for (const root of typeRoots) {
if (host.directoryExists(root)) {
+1
View File
@@ -1891,6 +1891,7 @@ namespace ts {
getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type;
getJsxIntrinsicTagNames(): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
getAmbientModules(): Symbol[];
// Should not be called directly. Should only be accessed through the Program instance.
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
+122 -47
View File
@@ -206,6 +206,24 @@ namespace FourSlash {
private inputFiles = ts.createMap<string>(); // Map between inputFile's fileName and its content for easily looking up when resolving references
private static getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) {
let result = "";
ts.forEach(displayParts, part => {
if (result) {
result += ",\n ";
}
else {
result = "[\n ";
}
result += JSON.stringify(part);
});
if (result) {
result += "\n]";
}
return result;
}
// Add input file which has matched file name with the given reference-file path.
// This is necessary when resolveReference flag is specified
private addMatchedInputFile(referenceFilePath: string, extensions: string[]) {
@@ -245,22 +263,31 @@ namespace FourSlash {
constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) {
// Create a new Services Adapter
this.cancellationToken = new TestCancellationToken();
const compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions);
if (compilationOptions.typeRoots) {
compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath));
}
let compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions);
compilationOptions.skipDefaultLibCheck = true;
const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions);
this.languageServiceAdapterHost = languageServiceAdapter.getHost();
this.languageService = languageServiceAdapter.getLanguageService();
// Initialize the language service with all the scripts
let startResolveFileRef: FourSlashFile;
ts.forEach(testData.files, file => {
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
this.inputFiles[file.fileName] = file.content;
if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") {
const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content);
assert.isTrue(configJson.config !== undefined);
// Extend our existing compiler options so that we can also support tsconfig only options
if (configJson.config.compilerOptions) {
const baseDirectory = ts.normalizePath(ts.getDirectoryPath(file.fileName));
const tsConfig = ts.convertCompilerOptionsFromJson(configJson.config.compilerOptions, baseDirectory, file.fileName);
if (!tsConfig.errors || !tsConfig.errors.length) {
compilationOptions = ts.extend(compilationOptions, tsConfig.options);
}
}
}
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference] === "true") {
startResolveFileRef = file;
}
@@ -270,6 +297,15 @@ namespace FourSlash {
}
});
if (compilationOptions.typeRoots) {
compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath));
}
const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions);
this.languageServiceAdapterHost = languageServiceAdapter.getHost();
this.languageService = languageServiceAdapter.getLanguageService();
if (startResolveFileRef) {
// Add the entry-point file itself into the languageServiceShimHost
this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content, /*isRootFile*/ true);
@@ -651,10 +687,10 @@ namespace FourSlash {
}
}
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string) {
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
const completions = this.getCompletionListAtCaret();
if (completions) {
this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind);
this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind, spanIndex);
}
else {
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${symbol}'.`);
@@ -670,25 +706,32 @@ namespace FourSlash {
* @param expectedText the text associated with the symbol
* @param expectedDocumentation the documentation text associated with the symbol
* @param expectedKind the kind of symbol (see ScriptElementKind)
* @param spanIndex the index of the range that the completion item's replacement text span should match
*/
public verifyCompletionListDoesNotContain(symbol: string, expectedText?: string, expectedDocumentation?: string, expectedKind?: string) {
public verifyCompletionListDoesNotContain(symbol: string, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) {
const that = this;
let replacementSpan: ts.TextSpan;
if (spanIndex !== undefined) {
replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex);
}
function filterByTextOrDocumentation(entry: ts.CompletionEntry) {
const details = that.getCompletionEntryDetails(entry.name);
const documentation = ts.displayPartsToString(details.documentation);
const text = ts.displayPartsToString(details.displayParts);
if (expectedText && expectedDocumentation) {
return (documentation === expectedDocumentation && text === expectedText) ? true : false;
// If any of the expected values are undefined, assume that users don't
// care about them.
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
return false;
}
else if (expectedText && !expectedDocumentation) {
return text === expectedText ? true : false;
else if (expectedText && text !== expectedText) {
return false;
}
else if (expectedDocumentation && !expectedText) {
return documentation === expectedDocumentation ? true : false;
else if (expectedDocumentation && documentation !== expectedDocumentation) {
return false;
}
// Because expectedText and expectedDocumentation are undefined, we assume that
// users don"t care to compare them so we will treat that entry as if the entry has matching text and documentation
// and keep it in the list of filtered entry.
return true;
}
@@ -712,6 +755,10 @@ namespace FourSlash {
if (expectedKind) {
error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + ".";
}
if (replacementSpan) {
const spanText = filterCompletions[0].replacementSpan ? stringify(filterCompletions[0].replacementSpan) : undefined;
error += "Expected replacement span: " + stringify(replacementSpan) + " to equal: " + spanText + ".";
}
this.raiseError(error);
}
}
@@ -777,6 +824,20 @@ namespace FourSlash {
ts.forEachProperty(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges));
}
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
const referencedSymbols = this.findReferencesAtCaret();
if (referencedSymbols.length === 0) {
this.raiseError("No referenced symbols found at current caret position");
}
else if (referencedSymbols.length > 1) {
this.raiseError("More than one referenced symbol found");
}
assert.equal(TestState.getDisplayPartsJson(referencedSymbols[0].definition.displayParts),
TestState.getDisplayPartsJson(expected), this.messageAtLastKnownMarker("referenced symbol definition display parts"));
}
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
for (let i = 0; i < references.length; i++) {
const reference = references[i];
@@ -811,6 +872,10 @@ namespace FourSlash {
return this.languageService.getReferencesAtPosition(this.activeFile.fileName, this.currentCaretPosition);
}
private findReferencesAtCaret() {
return this.languageService.findReferences(this.activeFile.fileName, this.currentCaretPosition);
}
public getSyntacticDiagnostics(expected: string) {
const diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName);
this.testDiagnostics(expected, diagnostics);
@@ -856,30 +921,12 @@ namespace FourSlash {
displayParts: ts.SymbolDisplayPart[],
documentation: ts.SymbolDisplayPart[]) {
function getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) {
let result = "";
ts.forEach(displayParts, part => {
if (result) {
result += ",\n ";
}
else {
result = "[\n ";
}
result += JSON.stringify(part);
});
if (result) {
result += "\n]";
}
return result;
}
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind"));
assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers"));
assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan"));
assert.equal(getDisplayPartsJson(actualQuickInfo.displayParts), getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
assert.equal(getDisplayPartsJson(actualQuickInfo.documentation), getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.displayParts), TestState.getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.documentation), TestState.getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
}
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean, ranges?: Range[]) {
@@ -2147,7 +2194,7 @@ namespace FourSlash {
return text.substring(startPos, endPos);
}
private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string) {
private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.name === name) {
@@ -2166,6 +2213,11 @@ namespace FourSlash {
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + name));
}
if (spanIndex !== undefined) {
const span = this.getTextSpanForRangeAtIndex(spanIndex);
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + name));
}
return;
}
}
@@ -2222,6 +2274,17 @@ namespace FourSlash {
return `line ${(pos.line + 1)}, col ${pos.character}`;
}
private getTextSpanForRangeAtIndex(index: number): ts.TextSpan {
const ranges = this.getRanges();
if (ranges && ranges.length > index) {
const range = ranges[index];
return { start: range.start, length: range.end - range.start };
}
else {
this.raiseError("Supplied span index: " + index + " does not exist in range list of size: " + (ranges ? 0 : ranges.length));
}
}
public getMarkerByName(markerName: string) {
const markerPos = this.testData.markerPositions[markerName];
if (markerPos === undefined) {
@@ -2245,6 +2308,10 @@ namespace FourSlash {
public resetCancelled(): void {
this.cancellationToken.resetCancelled();
}
private static textSpansEqual(a: ts.TextSpan, b: ts.TextSpan) {
return a && b && a.start === b.start && a.length === b.length;
}
}
export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) {
@@ -2253,12 +2320,16 @@ namespace FourSlash {
}
export function runFourSlashTestContent(basePath: string, testType: FourSlashTestType, content: string, fileName: string): void {
// Give file paths an absolute path for the virtual file system
const absoluteBasePath = ts.combinePaths(Harness.virtualFileSystemRoot, basePath);
const absoluteFileName = ts.combinePaths(Harness.virtualFileSystemRoot, fileName);
// Parse out the files and their metadata
const testData = parseTestData(basePath, content, fileName);
const state = new TestState(basePath, testType, testData);
const testData = parseTestData(absoluteBasePath, content, absoluteFileName);
const state = new TestState(absoluteBasePath, testType, testData);
const output = ts.transpileModule(content, { reportDiagnostics: true });
if (output.diagnostics.length > 0) {
throw new Error(`Syntax error in ${basePath}: ${output.diagnostics[0].messageText}`);
throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics[0].messageText}`);
}
runCode(output.outputText, state);
}
@@ -2811,12 +2882,12 @@ namespace FourSlashInterface {
// Verifies the completion list contains the specified symbol. The
// completion list is brought up if necessary
public completionListContains(symbol: string, text?: string, documentation?: string, kind?: string) {
public completionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
if (this.negative) {
this.state.verifyCompletionListDoesNotContain(symbol, text, documentation, kind);
this.state.verifyCompletionListDoesNotContain(symbol, text, documentation, kind, spanIndex);
}
else {
this.state.verifyCompletionListContains(symbol, text, documentation, kind);
this.state.verifyCompletionListContains(symbol, text, documentation, kind, spanIndex);
}
}
@@ -2945,6 +3016,10 @@ namespace FourSlashInterface {
this.state.verifyRangesReferenceEachOther(ranges);
}
public findReferencesDefinitionDisplayPartsAtCaretAre(expected: ts.SymbolDisplayPart[]) {
this.state.verifyDisplayPartsOfReferencedSymbol(expected);
}
public rangesWithSameTextReferenceEachOther() {
this.state.verifyRangesWithSameTextReferenceEachOther();
}
+22 -6
View File
@@ -458,6 +458,9 @@ namespace Harness {
// harness always uses one kind of new line
const harnessNewLine = "\r\n";
// Root for file paths that are stored in a virtual file system
export const virtualFileSystemRoot = "/";
namespace IOImpl {
declare class Enumerator {
public atEnd(): boolean;
@@ -1370,23 +1373,31 @@ namespace Harness {
// Produce baselines. The first gives the types for all expressions.
// The second gives symbols for all identifiers.
let e1: Error, e2: Error;
let typesError: Error, symbolsError: Error;
try {
checkBaseLines(/*isSymbolBaseLine*/ false);
}
catch (e) {
e1 = e;
typesError = e;
}
try {
checkBaseLines(/*isSymbolBaseLine*/ true);
}
catch (e) {
e2 = e;
symbolsError = e;
}
if (e1 || e2) {
throw e1 || e2;
if (typesError && symbolsError) {
throw new Error(typesError.message + ts.sys.newLine + symbolsError.message);
}
if (typesError) {
throw typesError;
}
if (symbolsError) {
throw symbolsError;
}
return;
@@ -1396,7 +1407,12 @@ namespace Harness {
const fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, fullExtension), () => fullBaseLine, opts);
// When calling this function from rwc-runner, the baselinePath will have no extension.
// As rwc test- file is stored in json which ".json" will get stripped off.
// When calling this function from compiler-runner, the baselinePath will then has either ".ts" or ".tsx" extension
const outputFileName = ts.endsWith(baselinePath, ".ts") || ts.endsWith(baselinePath, ".tsx") ?
baselinePath.replace(/\.tsx?/, fullExtension) : baselinePath.concat(fullExtension);
Harness.Baseline.runBaseline(outputFileName, () => fullBaseLine, opts);
}
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
+32 -8
View File
@@ -123,7 +123,7 @@ namespace Harness.LanguageService {
}
export class LanguageServiceAdapterHost {
protected fileNameToScript = ts.createMap<ScriptInfo>();
protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false);
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
protected settings = ts.getDefaultCompilerOptions()) {
@@ -135,22 +135,24 @@ namespace Harness.LanguageService {
public getFilenames(): string[] {
const fileNames: string[] = [];
ts.forEachProperty(this.fileNameToScript, (scriptInfo) => {
for (const virtualEntry of this.virtualFileSystem.getAllFileEntries()){
const scriptInfo = virtualEntry.content;
if (scriptInfo.isRootFile) {
// only include root files here
// usually it means that we won't include lib.d.ts in the list of root files so it won't mess the computation of compilation root dir.
fileNames.push(scriptInfo.fileName);
}
});
}
return fileNames;
}
public getScriptInfo(fileName: string): ScriptInfo {
return this.fileNameToScript[fileName];
const fileEntry = this.virtualFileSystem.traversePath(fileName);
return fileEntry && fileEntry.isFile() ? (<Utils.VirtualFile>fileEntry).content : undefined;
}
public addScript(fileName: string, content: string, isRootFile: boolean): void {
this.fileNameToScript[fileName] = new ScriptInfo(fileName, content, isRootFile);
this.virtualFileSystem.addFile(fileName, new ScriptInfo(fileName, content, isRootFile));
}
public editScript(fileName: string, start: number, end: number, newText: string) {
@@ -171,7 +173,7 @@ namespace Harness.LanguageService {
* @param col 0 based index
*/
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
const script: ScriptInfo = this.fileNameToScript[fileName];
const script: ScriptInfo = this.getScriptInfo(fileName);
assert.isOk(script);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
@@ -182,8 +184,14 @@ namespace Harness.LanguageService {
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost {
getCompilationSettings() { return this.settings; }
getCancellationToken() { return this.cancellationToken; }
getDirectories(path: string): string[] { return []; }
getCurrentDirectory(): string { return ""; }
getDirectories(path: string): string[] {
const dir = this.virtualFileSystem.traversePath(path);
if (dir && dir.isDirectory()) {
return ts.map((<Utils.VirtualDirectory>dir).getDirectories(), (d) => ts.combinePaths(path, d.name));
}
return [];
}
getCurrentDirectory(): string { return virtualFileSystemRoot; }
getDefaultLibFileName(): string { return Harness.Compiler.defaultLibFileName; }
getScriptFileNames(): string[] { return this.getFilenames(); }
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
@@ -196,6 +204,22 @@ namespace Harness.LanguageService {
return script ? script.version.toString() : undefined;
}
fileExists(fileName: string): boolean {
const script = this.getScriptSnapshot(fileName);
return script !== undefined;
}
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
return ts.matchFiles(path, extensions, exclude, include,
/*useCaseSensitiveFileNames*/false,
this.getCurrentDirectory(),
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
}
readFile(path: string, encoding?: string): string {
const snapshot = this.getScriptSnapshot(path);
return snapshot.getText(0, snapshot.getLength());
}
log(s: string): void { }
trace(s: string): void { }
error(s: string): void { }
+2 -1
View File
@@ -223,7 +223,8 @@ namespace RWC {
});
it("has the expected types", () => {
Harness.Compiler.doTypeAndSymbolBaseline(`${baseName}.types`, compilerResult, inputFiles
// We don't need to pass the extension here because "doTypeAndSymbolBaseline" will append appropriate extension of ".types" or ".symbols"
Harness.Compiler.doTypeAndSymbolBaseline(baseName, compilerResult, inputFiles
.concat(otherFiles)
.filter(file => !!compilerResult.program.getSourceFile(file.unitName))
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts);
@@ -1,79 +0,0 @@
class a {
constructor ( n : number ) ;
constructor ( s : string ) ;
constructor ( ns : any ) {
}
public pgF ( ) { } ;
public pv ;
public get d ( ) {
return 30 ;
}
public set d ( ) {
}
public static get p2 ( ) {
return { x : 30 , y : 40 } ;
}
private static d2 ( ) {
}
private static get p3 ( ) {
return "string" ;
}
private pv3 ;
private foo ( n : number ) : string ;
private foo ( s : string ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor ( n : number ) ;
constructor ( s : string ) ;
public pgF ( ) : void ;
public pv ;
public d : number ;
static p2 : { x : number ; y : number ; } ;
static d2 ( ) ;
static p3 ;
private pv3 ;
private foo ( s ) ;
}
class d {
private foo ( n : number ) : string ;
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
}
class e {
private foo ( ns : any ) {
return ns.toString ( ) ;
}
private foo ( s : string ) : string ;
private foo ( n : number ) : string ;
}
@@ -1,79 +0,0 @@
class a {
constructor(n: number);
constructor(s: string);
constructor(ns: any) {
}
public pgF() { };
public pv;
public get d() {
return 30;
}
public set d() {
}
public static get p2() {
return { x: 30, y: 40 };
}
private static d2() {
}
private static get p3() {
return "string";
}
private pv3;
private foo(n: number): string;
private foo(s: string): string;
private foo(ns: any) {
return ns.toString();
}
}
class b extends a {
}
class m1b {
}
interface m1ib {
}
class c extends m1b {
}
class ib2 implements m1ib {
}
declare class aAmbient {
constructor(n: number);
constructor(s: string);
public pgF(): void;
public pv;
public d: number;
static p2: { x: number; y: number; };
static d2();
static p3;
private pv3;
private foo(s);
}
class d {
private foo(n: number): string;
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
}
class e {
private foo(ns: any) {
return ns.toString();
}
private foo(s: string): string;
private foo(n: number): string;
}
@@ -1,4 +0,0 @@
class foo {
constructor (n?: number, m? = 5, o?: string = "") { }
x:number = 1?2:3;
}
@@ -1,4 +0,0 @@
class foo {
constructor(n?: number, m? = 5, o?: string = "") { }
x: number = 1 ? 2 : 3;
}
@@ -1,3 +0,0 @@
$ ( document ) . ready ( function ( ) {
alert ( 'i am ready' ) ;
} );
@@ -1,3 +0,0 @@
$(document).ready(function() {
alert('i am ready');
});
@@ -1,10 +0,0 @@
function foo ( x : { } ) { }
foo ( { } ) ;
interface bar {
x : { } ;
y : ( ) => { } ;
}
@@ -1,10 +0,0 @@
function foo(x: {}) { }
foo({});
interface bar {
x: {};
y: () => {};
}
@@ -1,112 +0,0 @@
// valid
( ) => 1 ;
( arg ) => 2 ;
arg => 2 ;
( arg = 1 ) => 3 ;
( arg ? ) => 4 ;
( arg : number ) => 5 ;
( arg : number = 0 ) => 6 ;
( arg ? : number ) => 7 ;
( ... arg : number [ ] ) => 8 ;
( arg1 , arg2 ) => 12 ;
( arg1 = 1 , arg2 =3 ) => 13 ;
( arg1 ? , arg2 ? ) => 14 ;
( arg1 : number , arg2 : number ) => 15 ;
( arg1 : number = 0 , arg2 : number = 1 ) => 16 ;
( arg1 ? : number , arg2 ? : number ) => 17 ;
( arg1 , ... arg2 : number [ ] ) => 18 ;
( arg1 , arg2 ? : number ) => 19 ;
// in paren
( ( ) => 21 ) ;
( ( arg ) => 22 ) ;
( ( arg = 1 ) => 23 ) ;
( ( arg ? ) => 24 ) ;
( ( arg : number ) => 25 ) ;
( ( arg : number = 0 ) => 26 ) ;
( ( arg ? : number ) => 27 ) ;
( ( ... arg : number [ ] ) => 28 ) ;
// in multiple paren
( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ;
// in ternary exression
false ? ( ) => 41 : null ;
false ? ( arg ) => 42 : null ;
false ? ( arg = 1 ) => 43 : null ;
false ? ( arg ? ) => 44 : null ;
false ? ( arg : number ) => 45 : null ;
false ? ( arg ? : number ) => 46 : null ;
false ? ( arg ? : number = 0 ) => 47 : null ;
false ? ( ... arg : number [ ] ) => 48 : null ;
// in ternary exression within paren
false ? ( ( ) => 51 ) : null ;
false ? ( ( arg ) => 52 ) : null ;
false ? ( ( arg = 1 ) => 53 ) : null ;
false ? ( ( arg ? ) => 54 ) : null ;
false ? ( ( arg : number ) => 55 ) : null ;
false ? ( ( arg ? : number ) => 56 ) : null ;
false ? ( ( arg ? : number = 0 ) => 57 ) : null ;
false ? ( ( ... arg : number [ ] ) => 58 ) : null ;
// ternary exression's else clause
false ? null : ( ) => 61 ;
false ? null : ( arg ) => 62 ;
false ? null : ( arg = 1 ) => 63 ;
false ? null : ( arg ? ) => 64 ;
false ? null : ( arg : number ) => 65 ;
false ? null : ( arg ? : number ) => 66 ;
false ? null : ( arg ? : number = 0 ) => 67 ;
false ? null : ( ... arg : number [ ] ) => 68 ;
// nested ternary expressions
( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ;
//multiple levels
( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ;
// In Expressions
( ( arg ) => 90 ) instanceof Function ;
( ( arg = 1 ) => 91 ) instanceof Function ;
( ( arg ? ) => 92 ) instanceof Function ;
( ( arg : number ) => 93 ) instanceof Function ;
( ( arg : number = 1 ) => 94 ) instanceof Function ;
( ( arg ? : number ) => 95 ) instanceof Function ;
( ( ... arg : number [ ] ) => 96 ) instanceof Function ;
'' + ( arg ) => 100 ;
( ( arg ) => 0 ) + '' + ( arg ) => 101 ;
( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ;
( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ;
( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ;
( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ;
( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ;
( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ;
( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ;
( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ;
// Function Parameters
function foo ( ... arg : any [ ] ) { }
foo (
( a ) => 110 ,
( ( a ) => 111 ) ,
( a ) => {
return 112 ;
} ,
( a ? ) => 113 ,
( a , b ? ) => 114 ,
( a : number ) => 115 ,
( a : number = 0 ) => 116 ,
( a = 0 ) => 117 ,
( a ? : number = 0 ) => 118 ,
( a ? , b ? : number = 0 ) => 118 ,
( ... a : number [ ] ) => 119 ,
( a , b ? = 0 , ... c : number [ ] ) => 120 ,
( a ) => ( b ) => ( c ) => 121 ,
false ? ( a ) => 0 : ( b ) => 122
) ;
@@ -1,112 +0,0 @@
// valid
() => 1;
(arg) => 2;
arg => 2;
(arg = 1) => 3;
(arg?) => 4;
(arg: number) => 5;
(arg: number = 0) => 6;
(arg?: number) => 7;
(...arg: number[]) => 8;
(arg1, arg2) => 12;
(arg1 = 1, arg2 = 3) => 13;
(arg1?, arg2?) => 14;
(arg1: number, arg2: number) => 15;
(arg1: number = 0, arg2: number = 1) => 16;
(arg1?: number, arg2?: number) => 17;
(arg1, ...arg2: number[]) => 18;
(arg1, arg2?: number) => 19;
// in paren
(() => 21);
((arg) => 22);
((arg = 1) => 23);
((arg?) => 24);
((arg: number) => 25);
((arg: number = 0) => 26);
((arg?: number) => 27);
((...arg: number[]) => 28);
// in multiple paren
(((((arg) => { return 32; }))));
// in ternary exression
false ? () => 41 : null;
false ? (arg) => 42 : null;
false ? (arg = 1) => 43 : null;
false ? (arg?) => 44 : null;
false ? (arg: number) => 45 : null;
false ? (arg?: number) => 46 : null;
false ? (arg?: number = 0) => 47 : null;
false ? (...arg: number[]) => 48 : null;
// in ternary exression within paren
false ? (() => 51) : null;
false ? ((arg) => 52) : null;
false ? ((arg = 1) => 53) : null;
false ? ((arg?) => 54) : null;
false ? ((arg: number) => 55) : null;
false ? ((arg?: number) => 56) : null;
false ? ((arg?: number = 0) => 57) : null;
false ? ((...arg: number[]) => 58) : null;
// ternary exression's else clause
false ? null : () => 61;
false ? null : (arg) => 62;
false ? null : (arg = 1) => 63;
false ? null : (arg?) => 64;
false ? null : (arg: number) => 65;
false ? null : (arg?: number) => 66;
false ? null : (arg?: number = 0) => 67;
false ? null : (...arg: number[]) => 68;
// nested ternary expressions
(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; };
//multiple levels
(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82;
// In Expressions
((arg) => 90) instanceof Function;
((arg = 1) => 91) instanceof Function;
((arg?) => 92) instanceof Function;
((arg: number) => 93) instanceof Function;
((arg: number = 1) => 94) instanceof Function;
((arg?: number) => 95) instanceof Function;
((...arg: number[]) => 96) instanceof Function;
'' + (arg) => 100;
((arg) => 0) + '' + (arg) => 101;
((arg = 1) => 0) + '' + (arg = 2) => 102;
((arg?) => 0) + '' + (arg?) => 103;
((arg: number) => 0) + '' + (arg: number) => 104;
((arg: number = 1) => 0) + '' + (arg: number = 2) => 105;
((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106;
((...arg: number[]) => 0) + '' + (...arg: number[]) => 107;
((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108;
((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108;
// Function Parameters
function foo(...arg: any[]) { }
foo(
(a) => 110,
((a) => 111),
(a) => {
return 112;
},
(a?) => 113,
(a, b?) => 114,
(a: number) => 115,
(a: number = 0) => 116,
(a = 0) => 117,
(a?: number = 0) => 118,
(a?, b?: number = 0) => 118,
(...a: number[]) => 119,
(a, b? = 0, ...c: number[]) => 120,
(a) => (b) => (c) => 121,
false ? (a) => 0 : (b) => 122
);
@@ -1,2 +0,0 @@
if(false){debugger;}
if ( false ) { debugger ; }
@@ -1,2 +0,0 @@
if (false) { debugger; }
if (false) { debugger; }
@@ -1,13 +0,0 @@
var fun1 = function ( ) {
var x = 'foo' ,
z = 'bar' ;
return x ;
},
fun2 = ( function ( f ) {
var fun = function ( ) {
console . log ( f ( ) ) ;
},
x = 'Foo' ;
return fun ;
} ( fun1 ) ) ;
@@ -1,13 +0,0 @@
var fun1 = function() {
var x = 'foo',
z = 'bar';
return x;
},
fun2 = (function(f) {
var fun = function() {
console.log(f());
},
x = 'Foo';
return fun;
} (fun1));
@@ -1,3 +0,0 @@
export class A {
}
@@ -1,6 +0,0 @@
module Foo {
}
import bar = Foo;
import bar2=Foo;
@@ -1,6 +0,0 @@
module Foo {
}
import bar = Foo;
import bar2 = Foo;
@@ -1,95 +0,0 @@
var a;var c , b;var $d
var $e
var f
a++;b++;
function f ( ) {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m (a[b[c][d]])];
break;
switch ( variable){
case 1: abc += 425;
break;
case 404 : a [x--/2]%=3 ;
break ;
case vari : v[--x ] *=++y*( m + n / k[z]);
for (a in b){
for (a = 0; a < 10; ++a) {
a++;--a;
if (a == b) {
a++;b--;
}
else
if (a == c){
++a;
(--c)+=d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--;++b;
a++
}
}
}
for (x in y) {
m-=m;
k=1+2+3+4;
}
}
break;
}
}
var a ={b:function(){}};
return {a:1,b:2}
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready ();
function pageLoad() {
$('#TextBox1' ) . unbind ( ) ;
$('#TextBox1' ) . datepicker ( ) ;
}
function pageLoad ( ) {
var webclass=[
{ 'student' :
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
} ,
{ 'student':
{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'}
} ,
{ 'student':
{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'}
}
];
$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList'));
}
$( document ).ready(function(){
alert('hello');
} ) ;
@@ -1,98 +0,0 @@
var a; var c, b; var $d
var $e
var f
a++; b++;
function f() {
for (i = 0; i < 10; i++) {
k = abc + 123 ^ d;
a = XYZ[m(a[b[c][d]])];
break;
switch (variable) {
case 1: abc += 425;
break;
case 404: a[x-- / 2] %= 3;
break;
case vari: v[--x] *= ++y * (m + n / k[z]);
for (a in b) {
for (a = 0; a < 10; ++a) {
a++; --a;
if (a == b) {
a++; b--;
}
else
if (a == c) {
++a;
(--c) += d;
$c = $a + --$b;
}
if (a == b)
if (a != b) {
if (a !== b)
if (a === b)
--a;
else
--a;
else {
a--; ++b;
a++
}
}
}
for (x in y) {
m -= m;
k = 1 + 2 + 3 + 4;
}
}
break;
}
}
var a = { b: function() { } };
return { a: 1, b: 2 }
}
var z = 1;
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 10; ++k) {
z++;
}
for (k = 0; k < 10; k += 2) {
z++;
}
$(document).ready();
function pageLoad() {
$('#TextBox1').unbind();
$('#TextBox1').datepicker();
}
function pageLoad() {
var webclass = [
{
'student':
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
},
{
'student':
{ 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' }
},
{
'student':
{ 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' }
}
];
$create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList'));
}
$(document).ready(function() {
alert('hello');
});
@@ -1,3 +0,0 @@
module Foo {
export module A . B . C { }
}
@@ -1,3 +0,0 @@
module Foo {
export module A.B.C { }
}
@@ -1,76 +0,0 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
} ;
var x : d ;
export function foo ( ) : d ;
}
import m4 = module ( "m4" ) ;
export var x4 = m4.x ;
export var d4 = m4.d ;
export var f4 = m4.foo ( ) ;
export module m1 {
declare export module "m2" {
export class d {
} ;
var x: d ;
export function foo ( ) : d ;
}
import m2 = module ( "m2" ) ;
import m3 = module ( "m4" ) ;
export var x2 = m2.x ;
export var d2 = m2.d ;
export var f2 = m2.foo ( ) ;
export var x3 = m3.x ;
export var d3 = m3.d ;
export var f3 = m3.foo ( ) ;
}
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
export module m5 {
export var x2 = m1.m2.x ;
export var d2 = m1.m2.d ;
export var f2 = m1.m2.foo ( ) ;
export var x3 = m1.m3.x ;
export var d3 = m1.m3.d ;
export var f3 = m1.m3.foo ( ) ;
}
@@ -1,76 +0,0 @@
module mod1 {
export class b {
}
class d {
}
export interface ib {
}
}
module m2 {
export module m3 {
export class c extends mod1.b {
}
export class ib2 implements mod1.ib {
}
}
}
class c extends mod1.b {
}
class ib2 implements mod1.ib {
}
declare export module "m4" {
export class d {
};
var x: d;
export function foo(): d;
}
import m4 = module("m4");
export var x4 = m4.x;
export var d4 = m4.d;
export var f4 = m4.foo();
export module m1 {
declare export module "m2" {
export class d {
};
var x: d;
export function foo(): d;
}
import m2 = module("m2");
import m3 = module("m4");
export var x2 = m2.x;
export var d2 = m2.d;
export var f2 = m2.foo();
export var x3 = m3.x;
export var d3 = m3.d;
export var f3 = m3.foo();
}
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
export module m5 {
export var x2 = m1.m2.x;
export var d2 = m1.m2.d;
export var f2 = m1.m2.foo();
export var x3 = m1.m3.x;
export var d3 = m1.m3.d;
export var f3 = m1.m3.foo();
}
@@ -1,27 +0,0 @@
var x = {foo: 1,
bar: "tt",
boo: 1 + 5};
var x2 = {foo: 1,
bar: "tt",boo:1+5};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b : 2}
};
var x={ };
var y = {};
@@ -1,31 +0,0 @@
var x = {
foo: 1,
bar: "tt",
boo: 1 + 5
};
var x2 = {
foo: 1,
bar: "tt", boo: 1 + 5
};
function Foo() {
var typeICalc = {
clear: {
"()": [1, 2, 3]
}
}
}
// Rule for object literal members for the "value" of the memebr to follow the indent
// of the member, i.e. the relative position of the value is maintained when the member
// is indented.
var x2 = {
foo:
3,
'bar':
{ a: 1, b: 2 }
};
var x = {};
var y = {};
@@ -1,32 +0,0 @@
function f( ) {
var x = 3;
var z = 2 ;
a = z ++ - 2 * x ;
for ( ; ; ) {
a+=(g +g)*a%t;
b -- ;
}
switch ( a )
{
case 1 : {
a ++ ;
b--;
if(a===a)
return;
else
{
for(a in b)
if(a!=a)
{
for(a in b)
{
a++;
}
}
}
}
default:
break;
}
}
@@ -1,28 +0,0 @@
function f() {
var x = 3;
var z = 2;
a = z++ - 2 * x;
for (; ;) {
a += (g + g) * a % t;
b--;
}
switch (a) {
case 1: {
a++;
b--;
if (a === a)
return;
else {
for (a in b)
if (a != a) {
for (a in b) {
a++;
}
}
}
}
default:
break;
}
}
@@ -1 +0,0 @@
var a=b+c^d-e*++f;
@@ -1 +0,0 @@
var a = b + c ^ d - e * ++f;
@@ -1 +0,0 @@
class test { constructor () { } }
@@ -1 +0,0 @@
class test { constructor() { } }
@@ -1,10 +0,0 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob
{
Blah=1, Bleah=2
}
}
@@ -1,9 +0,0 @@
module Tools {
export enum NodeType {
Error,
Comment,
}
export enum foob {
Blah = 1, Bleah = 2
}
}
@@ -1,65 +0,0 @@
module MyModule
{
module A.B.C {
module F {
}
}
interface Blah
{
boo: string;
}
class Foo
{
}
class Foo2 {
public foo():number {
return 5 * 6;
}
public foo2() {
if (1 === 2)
{
var y : number= 76;
return y;
}
while (2 == 3) {
if ( y == null ) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a:number, b:number):number
{
return 0;
}
function bar(a:number, b:number) :number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}
@@ -1,58 +0,0 @@
module MyModule {
module A.B.C {
module F {
}
}
interface Blah {
boo: string;
}
class Foo {
}
class Foo2 {
public foo(): number {
return 5 * 6;
}
public foo2() {
if (1 === 2) {
var y: number = 76;
return y;
}
while (2 == 3) {
if (y == null) {
}
}
}
public foo3() {
if (1 === 2)
//comment preventing line merging
{
var y = 76;
return y;
}
}
}
}
function foo(a: number, b: number): number {
return 0;
}
function bar(a: number, b: number): number[] {
return [];
}
module BugFix3 {
declare var f: {
(): any;
(x: number): string;
foo: number;
};
}
@@ -1,17 +0,0 @@
function f(a,b,c,d){
for(var i=0;i<10;i++){
var a=0;
var b=a+a+a*a%a/2-1;
b+=a;
++b;
f(a,b,c,d);
if(1===1){
var m=function(e,f){
return e^f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}
@@ -1,17 +0,0 @@
function f(a, b, c, d) {
for (var i = 0; i < 10; i++) {
var a = 0;
var b = a + a + a * a % a / 2 - 1;
b += a;
++b;
f(a, b, c, d);
if (1 === 1) {
var m = function(e, f) {
return e ^ f;
}
}
}
}
for (var i = 0 ; i < this.foo(); i++) {
}
@@ -1,9 +0,0 @@
with (foo.bar)
{
}
with (bar.blah)
{
}
@@ -1,6 +0,0 @@
with (foo.bar) {
}
with (bar.blah) {
}
+40 -16
View File
@@ -16,7 +16,7 @@ namespace Utils {
}
export class VirtualFile extends VirtualFileSystemEntry {
content: string;
content?: Harness.LanguageService.ScriptInfo;
isFile() { return true; }
}
@@ -73,7 +73,7 @@ namespace Utils {
}
}
addFile(name: string, content?: string): VirtualFile {
addFile(name: string, content?: Harness.LanguageService.ScriptInfo): VirtualFile {
const entry = this.getFileSystemEntry(name);
if (entry === undefined) {
const file = new VirtualFile(this.fileSystem, name);
@@ -111,6 +111,7 @@ namespace Utils {
getFileSystemEntries() { return this.root.getFileSystemEntries(); }
addDirectory(path: string) {
path = ts.normalizePath(path);
const components = ts.getNormalizedPathComponents(path, this.currentDirectory);
let directory: VirtualDirectory = this.root;
for (const component of components) {
@@ -123,8 +124,8 @@ namespace Utils {
return directory;
}
addFile(path: string, content?: string) {
const absolutePath = ts.getNormalizedAbsolutePath(path, this.currentDirectory);
addFile(path: string, content?: Harness.LanguageService.ScriptInfo) {
const absolutePath = ts.normalizePath(ts.getNormalizedAbsolutePath(path, this.currentDirectory));
const fileName = ts.getBaseFileName(path);
const directoryPath = ts.getDirectoryPath(absolutePath);
const directory = this.addDirectory(directoryPath);
@@ -141,6 +142,7 @@ namespace Utils {
}
traversePath(path: string) {
path = ts.normalizePath(path);
let directory: VirtualDirectory = this.root;
for (const component of ts.getNormalizedPathComponents(path, this.currentDirectory)) {
const entry = directory.getFileSystemEntry(component);
@@ -157,6 +159,40 @@ namespace Utils {
return directory;
}
/**
* Reads the directory at the given path and retrieves a list of file names and a list
* of directory names within it. Suitable for use with ts.matchFiles()
* @param path The path to the directory to be read
*/
getAccessibleFileSystemEntries(path: string) {
const entry = this.traversePath(path);
if (entry && entry.isDirectory()) {
const directory = <VirtualDirectory>entry;
return {
files: ts.map(directory.getFiles(), f => f.name),
directories: ts.map(directory.getDirectories(), d => d.name)
};
}
return { files: [], directories: [] };
}
getAllFileEntries() {
const fileEntries: VirtualFile[] = [];
getFilesRecursive(this.root, fileEntries);
return fileEntries;
function getFilesRecursive(dir: VirtualDirectory, result: VirtualFile[]) {
const files = dir.getFiles();
const dirs = dir.getDirectories();
for (const file of files) {
result.push(file);
}
for (const subDir of dirs) {
getFilesRecursive(subDir, result);
}
}
}
}
export class MockParseConfigHost extends VirtualFileSystem implements ts.ParseConfigHost {
@@ -170,17 +206,5 @@ namespace Utils {
readDirectory(path: string, extensions: string[], excludes: string[], includes: string[]) {
return ts.matchFiles(path, extensions, excludes, includes, this.useCaseSensitiveFileNames, this.currentDirectory, (path: string) => this.getAccessibleFileSystemEntries(path));
}
getAccessibleFileSystemEntries(path: string) {
const entry = this.traversePath(path);
if (entry && entry.isDirectory()) {
const directory = <VirtualDirectory>entry;
return {
files: ts.map(directory.getFiles(), f => f.name),
directories: ts.map(directory.getDirectories(), d => d.name)
};
}
return { files: [], directories: [] };
}
}
}
+12 -1
View File
@@ -216,7 +216,18 @@ namespace ts.server {
return {
isMemberCompletion: false,
isNewIdentifierLocation: false,
entries: response.body
entries: response.body.map(entry => {
if (entry.replacementSpan !== undefined) {
const { name, kind, kindModifiers, sortText, replacementSpan} = entry;
const convertedSpan = createTextSpanFromBounds(this.lineOffsetToPosition(fileName, replacementSpan.start),
this.lineOffsetToPosition(fileName, replacementSpan.end));
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan };
}
return entry as { name: string, kind: string, kindModifiers: string, sortText: string };
})
};
}
+1
View File
@@ -341,6 +341,7 @@ namespace ts.server {
// capture list of projects since detachAllProjects will wipe out original list
const containingProjects = info.containingProjects.slice();
info.detachAllProjects();
// update projects to make sure that set of referenced files is correct
+1 -1
View File
@@ -146,7 +146,7 @@ namespace ts.server {
}
getCurrentDirectory(): string {
return "";
return this.host.getCurrentDirectory();
}
resolvePath(path: string): string {
+5
View File
@@ -965,6 +965,11 @@ declare namespace ts.server.protocol {
* is often the same as the name but may be different in certain circumstances.
*/
sortText: string;
/**
* An optional span that indicates the text to be replaced by this completion item. If present,
* this span should be used instead of the default one.
*/
replacementSpan?: TextSpan;
}
/**
+11 -1
View File
@@ -923,7 +923,17 @@ namespace ts.server {
if (simplifiedResult) {
return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => {
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
result.push(entry);
const { name, kind, kindModifiers, sortText, replacementSpan } = entry;
let convertedSpan: protocol.TextSpan = undefined;
if (replacementSpan) {
convertedSpan = {
start: scriptInfo.positionToLineOffset(replacementSpan.start),
end: scriptInfo.positionToLineOffset(replacementSpan.start + replacementSpan.length)
};
}
result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan });
}
return result;
}, []).sort((a, b) => a.name.localeCompare(b.name));
+553 -19
View File
@@ -1177,6 +1177,14 @@ namespace ts {
error?(s: string): void;
useCaseSensitiveFileNames?(): boolean;
/*
* LS host can optionally implement these methods to support completions for module specifiers.
* Without these methods, only completions for ambient modules will be provided.
*/
readDirectory?(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[];
readFile?(path: string, encoding?: string): string;
fileExists?(path: string): boolean;
/*
* LS host can optionally implement this method if it wants to be completely in charge of module name resolution.
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
@@ -1185,6 +1193,11 @@ namespace ts {
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
directoryExists?(directoryName: string): boolean;
/*
* getDirectories is also required for full import and type reference completions. Without it defined, certain
* completions will not be provided
*/
getDirectories?(directoryName: string): string[];
}
@@ -1442,8 +1455,12 @@ namespace ts {
containerName: string;
}
export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo {
displayParts: SymbolDisplayPart[];
}
export interface ReferencedSymbol {
definition: DefinitionInfo;
definition: ReferencedSymbolDefinitionInfo;
references: ReferenceEntry[];
}
@@ -1540,6 +1557,12 @@ namespace ts {
kind: string; // see ScriptElementKind
kindModifiers: string; // see ScriptElementKindModifier, comma separated
sortText: string;
/**
* An optional span that indicates the text to be replaced by this completion item. It will be
* set if the required span differs from the one generated by the default replacement behavior and should
* be used in that case
*/
replacementSpan?: TextSpan;
}
export interface CompletionEntryDetails {
@@ -1822,6 +1845,10 @@ namespace ts {
export const constElement = "const";
export const letElement = "let";
export const directory = "directory";
export const externalModuleName = "external module name";
}
export namespace ScriptElementKindModifier {
@@ -1910,6 +1937,11 @@ namespace ts {
owners: string[];
}
interface VisibleModuleInfo {
moduleName: string;
moduleDir: string;
}
export interface DisplayPartsSymbolWriter extends SymbolWriter {
displayParts(): SymbolDisplayPart[];
}
@@ -2062,7 +2094,15 @@ namespace ts {
sourceMapText?: string;
}
/**
* Matches a triple slash reference directive with an incomplete string literal for its path. Used
* to determine if the caret is currently within the string literal and capture the literal fragment
* for completions.
* For example, this matches /// <reference path="fragment
*/
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3]*)$/;
const nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
let commandLineOptionsStringToEnum: CommandLineOptionOfCustomType[];
@@ -2890,13 +2930,17 @@ namespace ts {
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
if (node.kind === SyntaxKind.StringLiteral) {
return isNameOfModuleDeclaration(node) ||
(isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node);
return isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node);
}
return false;
}
function isExpressionOfExternalModuleImportEqualsDeclaration(node: Node) {
return isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node;
}
/** Returns true if the position is within a comment */
function isInsideComment(sourceFile: SourceFile, token: Node, position: number): boolean {
// The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment
@@ -4291,6 +4335,10 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
if (isInReferenceComment(sourceFile, position)) {
return getTripleSlashReferenceCompletion(sourceFile, position);
}
if (isInString(sourceFile, position)) {
return getStringLiteralCompletionEntries(sourceFile, position);
}
@@ -4460,6 +4508,13 @@ namespace ts {
// a['/*completion position*/']
return getStringLiteralCompletionEntriesFromElementAccess(node.parent);
}
else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, false)) {
// Get all known external module names or complete a path to a module
// i.e. import * as ns from "/*completion position*/";
// import x = require("/*completion position*/");
// var y = require("/*completion position*/");
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node);
}
else {
const argumentInfo = SignatureHelp.getContainingArgumentInfo(node, position, sourceFile);
if (argumentInfo) {
@@ -4552,6 +4607,486 @@ namespace ts {
}
}
}
function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral): CompletionInfo {
const literalValue = normalizeSlashes(node.text);
const scriptPath = node.getSourceFile().path;
const scriptDirectory = getDirectoryPath(scriptPath);
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
let entries: CompletionEntry[];
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
const compilerOptions = program.getCompilerOptions();
if (compilerOptions.rootDirs) {
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
compilerOptions.rootDirs, literalValue, scriptDirectory, getSupportedExtensions(program.getCompilerOptions()), /*includeExtensions*/false, span, scriptPath);
}
else {
entries = getCompletionEntriesForDirectoryFragment(
literalValue, scriptDirectory, getSupportedExtensions(program.getCompilerOptions()), /*includeExtensions*/false, span, scriptPath);
}
}
else {
// Check for node modules
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span);
}
return {
isMemberCompletion: false,
isNewIdentifierLocation: true,
entries
};
}
/**
* Takes a script path and returns paths for all potential folders that could be merged with its
* containing folder via the "rootDirs" compiler option
*/
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
// Make all paths absolute/normalized if they are not already
rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
// Determine the path to the directory containing the script relative to the root directory it is contained within
let relativeDirectory: string;
for (const rootDirectory of rootDirs) {
if (containsPath(rootDirectory, scriptPath, basePath, ignoreCase)) {
relativeDirectory = scriptPath.substr(rootDirectory.length);
break;
}
}
// Now find a path for each potential directory that is to be merged with the one containing the script
return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)));
}
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string): CompletionEntry[] {
const basePath = program.getCompilerOptions().project || host.getCurrentDirectory();
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
const result: CompletionEntry[] = [];
for (const baseDirectory of baseDirectories) {
getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, exclude, result);
}
return result;
}
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] {
fragment = getDirectoryPath(fragment);
if (!fragment) {
fragment = "./";
}
else {
fragment = ensureTrailingDirectorySeparator(fragment);
}
const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment));
const baseDirectory = getDirectoryPath(absolutePath);
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
if (tryDirectoryExists(host, baseDirectory)) {
// Enumerate the available files if possible
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
if (files) {
const foundFiles = createMap<boolean>();
for (let filePath of files) {
filePath = normalizePath(filePath);
if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) {
continue;
}
const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
if (!foundFiles[foundFileName]) {
foundFiles[foundFileName] = true;
}
}
for (const foundFile in foundFiles) {
result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span));
}
}
// If possible, get folder completion as well
const directories = tryGetDirectories(host, baseDirectory);
if (directories) {
for (const directory of directories) {
const directoryName = getBaseFileName(normalizePath(directory));
result.push(createCompletionEntryForModule(directoryName, ScriptElementKind.directory, span));
}
}
}
return result;
}
/**
* Check all of the declared modules and those in node modules. Possible sources of modules:
* Modules that are found by the type checker
* Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
* Modules from node_modules (i.e. those listed in package.json)
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, span: TextSpan): CompletionEntry[] {
const options = program.getCompilerOptions();
const { baseUrl, paths } = options;
let result: CompletionEntry[];
if (baseUrl) {
const fileExtensions = getSupportedExtensions(options);
const projectDir = options.project || host.getCurrentDirectory();
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span);
if (paths) {
for (const path in paths) {
if (paths.hasOwnProperty(path)) {
if (path === "*") {
if (paths[path]) {
for (const pattern of paths[path]) {
for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions)) {
result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span));
}
}
}
}
else if (startsWith(path, fragment)) {
const entry = paths[path] && paths[path].length === 1 && paths[path][0];
if (entry) {
result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span));
}
}
}
}
}
}
else {
result = [];
}
getCompletionEntriesFromTypings(host, options, scriptPath, span, result);
for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, options)) {
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
}
return result;
}
function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: string[]): string[] {
if (host.readDirectory) {
const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined;
if (parsed) {
// The prefix has two effective parts: the directory path and the base component after the filepath that is not a
// full directory component. For example: directory/path/of/prefix/base*
const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix);
const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix);
const normalizedPrefixBase = getBaseFileName(normalizedPrefix);
const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1;
// Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory;
const normalizedSuffix = normalizePath(parsed.suffix);
const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory);
const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
// If we have a suffix, then we need to read the directory all the way down. We could create a glob
// that encodes the suffix, but we would have to escape the character "?" which readDirectory
// doesn't support. For now, this is safer but slower
const includeGlob = normalizedSuffix ? "**/*" : "./*";
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]);
if (matches) {
const result: string[] = [];
// Trim away prefix and suffix
for (const match of matches) {
const normalizedMatch = normalizePath(match);
if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) {
continue;
}
const start = completePrefix.length;
const length = normalizedMatch.length - start - normalizedSuffix.length;
result.push(removeFileExtension(normalizedMatch.substr(start, length)));
}
return result;
}
}
}
return undefined;
}
function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions): string[] {
// Check If this is a nested module
const isNestedModule = fragment.indexOf(directorySeparator) !== -1;
const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined;
// Get modules that the type checker picked up
const ambientModules = map(program.getTypeChecker().getAmbientModules(), sym => stripQuotes(sym.name));
let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string
// after the last '/' that appears in the fragment because that's where the replacement span
// starts
if (isNestedModule) {
const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment);
nonRelativeModules = map(nonRelativeModules, moduleName => {
if (startsWith(fragment, moduleNameWithSeperator)) {
return moduleName.substr(moduleNameWithSeperator.length);
}
return moduleName;
});
}
if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) {
for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) {
if (!isNestedModule) {
nonRelativeModules.push(visibleModule.moduleName);
}
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
if (nestedFiles) {
for (let f of nestedFiles) {
f = normalizePath(f);
const nestedModule = removeFileExtension(getBaseFileName(f));
nonRelativeModules.push(nestedModule);
}
}
}
}
}
return deduplicate(nonRelativeModules);
}
function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number): CompletionInfo {
const token = getTokenAtPosition(sourceFile, position);
if (!token) {
return undefined;
}
const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos);
if (!commentRanges || !commentRanges.length) {
return undefined;
}
const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange);
if (!range) {
return undefined;
}
const text = sourceFile.text.substr(range.pos, position - range.pos);
const match = tripleSlashDirectiveFragmentRegex.exec(text);
if (match) {
const prefix = match[1];
const kind = match[2];
const toComplete = match[3];
const scriptPath = getDirectoryPath(sourceFile.path);
let entries: CompletionEntry[];
if (kind === "path") {
// Give completions for a relative path
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(program.getCompilerOptions()), /*includeExtensions*/true, span, sourceFile.path);
}
else {
// Give completions based on the typings available
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
entries = getCompletionEntriesFromTypings(host, program.getCompilerOptions(), scriptPath, span);
}
return {
isMemberCompletion: false,
isNewIdentifierLocation: true,
entries
};
}
return undefined;
}
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
// Check for typings specified in compiler options
if (options.types) {
for (const moduleName of options.types) {
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
}
}
else if (host.getDirectories) {
const typeRoots = getEffectiveTypeRoots(options, host.getCurrentDirectory());
for (const root of typeRoots) {
getCompletionEntriesFromDirectories(host, options, root, span, result);
}
}
if (host.getDirectories) {
// Also get all @types typings installed in visible node_modules directories
for (const package of findPackageJsons(scriptPath)) {
const typesDir = combinePaths(getDirectoryPath(package), "node_modules/@types");
getCompletionEntriesFromDirectories(host, options, typesDir, span, result);
}
}
return result;
}
function getCompletionEntriesFromDirectories(host: LanguageServiceHost, options: CompilerOptions, directory: string, span: TextSpan, result: CompletionEntry[]) {
if (host.getDirectories && tryDirectoryExists(host, directory)) {
const directories = tryGetDirectories(host, directory);
if (directories) {
for (let typeDirectory of directories) {
typeDirectory = normalizePath(typeDirectory);
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span));
}
}
}
}
function findPackageJsons(currentDir: string): string[] {
const paths: string[] = [];
let currentConfigPath: string;
while (true) {
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
if (currentConfigPath) {
paths.push(currentConfigPath);
currentDir = getDirectoryPath(currentConfigPath);
const parent = getDirectoryPath(currentDir);
if (currentDir === parent) {
break;
}
currentDir = parent;
}
else {
break;
}
}
return paths;
}
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string) {
const result: VisibleModuleInfo[] = [];
if (host.readFile && host.fileExists) {
for (const packageJson of findPackageJsons(scriptPath)) {
const package = tryReadingPackageJson(packageJson);
if (!package) {
return;
}
const nodeModulesDir = combinePaths(getDirectoryPath(packageJson), "node_modules");
const foundModuleNames: string[] = [];
// Provide completions for all non @types dependencies
for (const key of nodeModulesDependencyKeys) {
addPotentialPackageNames(package[key], foundModuleNames);
}
for (const moduleName of foundModuleNames) {
const moduleDir = combinePaths(nodeModulesDir, moduleName);
result.push({
moduleName,
moduleDir
});
}
}
}
return result;
function tryReadingPackageJson(filePath: string) {
try {
const fileText = tryReadFile(host, filePath);
return fileText ? JSON.parse(fileText) : undefined;
}
catch (e) {
return undefined;
}
}
function addPotentialPackageNames(dependencies: any, result: string[]) {
if (dependencies) {
for (const dep in dependencies) {
if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) {
result.push(dep);
}
}
}
}
}
function createCompletionEntryForModule(name: string, kind: string, replacementSpan: TextSpan): CompletionEntry {
return { name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: name, replacementSpan };
}
// Replace everything after the last directory seperator that appears
function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan {
const index = text.lastIndexOf(directorySeparator);
const offset = index !== -1 ? index + 1 : 0;
return { start: textStart + offset, length: text.length - offset };
}
// Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
function isPathRelativeToScript(path: string) {
if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) {
const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1;
const slashCharCode = path.charCodeAt(slashIndex);
return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash;
}
return false;
}
function normalizeAndPreserveTrailingSlash(path: string) {
return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path);
}
function tryGetDirectories(host: LanguageServiceHost, directoryName: string): string[] {
return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
}
function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
}
function tryReadFile(host: LanguageServiceHost, path: string): string {
return tryIOAndConsumeErrors(host, host.readFile, path);
}
function tryFileExists(host: LanguageServiceHost, path: string): boolean {
return tryIOAndConsumeErrors(host, host.fileExists, path);
}
function tryDirectoryExists(host: LanguageServiceHost, path: string): boolean {
try {
return directoryProbablyExists(path, host);
}
catch (e) {}
return undefined;
}
function tryIOAndConsumeErrors<T>(host: LanguageServiceHost, toApply: (...a: any[]) => T, ...args: any[]) {
try {
return toApply && toApply.apply(host, args);
}
catch (e) {}
return undefined;
}
}
function getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails {
@@ -6194,7 +6729,7 @@ namespace ts {
return result;
function getDefinition(symbol: Symbol): DefinitionInfo {
function getDefinition(symbol: Symbol): ReferencedSymbolDefinitionInfo {
const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node);
const name = map(info.displayParts, p => p.text).join("");
const declarations = symbol.declarations;
@@ -6208,7 +6743,8 @@ namespace ts {
name,
kind: info.symbolKind,
fileName: declarations[0].getSourceFile().fileName,
textSpan: createTextSpan(declarations[0].getStart(), 0)
textSpan: createTextSpan(declarations[0].getStart(), 0),
displayParts: info.displayParts
};
}
@@ -6403,13 +6939,14 @@ namespace ts {
}
});
const definition: DefinitionInfo = {
const definition: ReferencedSymbolDefinitionInfo = {
containerKind: "",
containerName: "",
fileName: targetLabel.getSourceFile().fileName,
kind: ScriptElementKind.label,
name: labelName,
textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd())
textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()),
displayParts: [displayPart(labelName, SymbolDisplayPartKind.text)]
};
return [{ definition, references }];
@@ -6456,7 +6993,6 @@ namespace ts {
symbolToIndex: number[]): void {
const sourceFile = container.getSourceFile();
const tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
const start = findInComments ? container.getFullStart() : container.getStart();
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd());
@@ -6538,15 +7074,6 @@ namespace ts {
return result[index];
}
function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
return isInCommentHelper(sourceFile, position, isNonReferenceComment);
function isNonReferenceComment(c: CommentRange): boolean {
const commentText = sourceFile.text.substring(c.pos, c.end);
return !tripleSlashDirectivePrefixRegex.test(commentText);
}
}
}
function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] {
@@ -6649,6 +7176,11 @@ namespace ts {
getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
}
const thisOrSuperSymbol = typeChecker.getSymbolAtLocation(thisOrSuperKeyword);
const displayParts = thisOrSuperSymbol && getSymbolDisplayPartsDocumentationAndSymbolKind(
thisOrSuperSymbol, thisOrSuperKeyword.getSourceFile(), getContainerNode(thisOrSuperKeyword), thisOrSuperKeyword).displayParts;
return [{
definition: {
containerKind: "",
@@ -6656,7 +7188,8 @@ namespace ts {
fileName: node.getSourceFile().fileName,
kind: ScriptElementKind.variableElement,
name: "this",
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd())
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd()),
displayParts
},
references: references
}];
@@ -6727,7 +7260,8 @@ namespace ts {
fileName: node.getSourceFile().fileName,
kind: ScriptElementKind.variableElement,
name: type.text,
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd())
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd()),
displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)]
},
references: references
}];
+26
View File
@@ -67,6 +67,10 @@ namespace ts {
getProjectVersion?(): string;
useCaseSensitiveFileNames?(): boolean;
readDirectory(rootDir: string, extension: string, basePaths?: string, excludeEx?: string, includeFileEx?: string, includeDirEx?: string, depth?: number): string;
readFile(path: string, encoding?: string): string;
fileExists(path: string): boolean;
getModuleResolutionsForFile?(fileName: string): string;
getTypeReferenceDirectiveResolutionsForFile?(fileName: string): string;
directoryExists(directoryName: string): boolean;
@@ -421,6 +425,28 @@ namespace ts {
public getDefaultLibFileName(options: CompilerOptions): string {
return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
}
public readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[], depth?: number): string[] {
const pattern = getFileMatcherPatterns(path, extensions, exclude, include,
this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory());
return JSON.parse(this.shimHost.readDirectory(
path,
JSON.stringify(extensions),
JSON.stringify(pattern.basePaths),
pattern.excludePattern,
pattern.includeFilePattern,
pattern.includeDirectoryPattern,
depth
));
}
public readFile(path: string, encoding?: string): string {
return this.shimHost.readFile(path, encoding);
}
public fileExists(path: string): boolean {
return this.shimHost.fileExists(path);
}
}
/** A cancellation that throttles calls to the host */
+26
View File
@@ -1,6 +1,9 @@
// These utilities are common to multiple language service features.
/* @internal */
namespace ts {
// Matches the beginning of a triple slash directive
const tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
export interface ListItemInfo {
listItemIndex: number;
list: Node;
@@ -704,6 +707,29 @@ namespace ts {
return false;
}
export function hasTrailingDirectorySeparator(path: string) {
const lastCharacter = path.charAt(path.length - 1);
return lastCharacter === "/" || lastCharacter === "\\";
}
export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean {
return isInCommentHelper(sourceFile, position, isReferenceComment);
function isReferenceComment(c: CommentRange): boolean {
const commentText = sourceFile.text.substring(c.pos, c.end);
return tripleSlashDirectivePrefixRegex.test(commentText);
}
}
export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean {
return isInCommentHelper(sourceFile, position, isNonReferenceComment);
function isNonReferenceComment(c: CommentRange): boolean {
const commentText = sourceFile.text.substring(c.pos, c.end);
return !tripleSlashDirectivePrefixRegex.test(commentText);
}
}
}
// Display-part writer helpers
@@ -1,8 +1,8 @@
EmitSkipped: true
Diagnostics:
Cannot write file 'tests/cases/fourslash/b.js' because it would overwrite input file.
Cannot write file '/tests/cases/fourslash/b.js' because it would overwrite input file.
EmitSkipped: false
FileName : tests/cases/fourslash/a.js
FileName : /tests/cases/fourslash/a.js
function foo2() { return 30; } // no error - should emit a.js
@@ -0,0 +1,16 @@
tests/cases/conformance/decorators/class/constructableDecoratorOnClass01.ts(4,1): error TS1238: Unable to resolve signature of class decorator when called as an expression.
Cannot invoke an expression whose type lacks a call signature.
==== tests/cases/conformance/decorators/class/constructableDecoratorOnClass01.ts (1 errors) ====
class CtorDtor {}
@CtorDtor
~~~~~~~~~
!!! error TS1238: Unable to resolve signature of class decorator when called as an expression.
!!! error TS1238: Cannot invoke an expression whose type lacks a call signature.
class C {
}
@@ -0,0 +1,30 @@
//// [constructableDecoratorOnClass01.ts]
class CtorDtor {}
@CtorDtor
class C {
}
//// [constructableDecoratorOnClass01.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var CtorDtor = (function () {
function CtorDtor() {
}
return CtorDtor;
}());
var C = (function () {
function C() {
}
C = __decorate([
CtorDtor
], C);
return C;
}());
@@ -0,0 +1,13 @@
=== tests/cases/conformance/decorators/class/constructableDecoratorOnClass01.ts ===
class CtorDtor {}
>CtorDtor : Symbol(CtorDtor, Decl(constructableDecoratorOnClass01.ts, 0, 0))
@CtorDtor
>CtorDtor : Symbol(CtorDtor, Decl(constructableDecoratorOnClass01.ts, 0, 0))
class C {
>C : Symbol(C, Decl(constructableDecoratorOnClass01.ts, 1, 17))
}
@@ -0,0 +1,13 @@
=== tests/cases/conformance/decorators/class/constructableDecoratorOnClass01.ts ===
class CtorDtor {}
>CtorDtor : CtorDtor
@CtorDtor
>CtorDtor : typeof CtorDtor
class C {
>C : C
}
@@ -1,20 +1,18 @@
tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'.
Property 'd' is missing in type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2324: Property 'd' is missing in type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'.
Property 'd' is missing in type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'.
tests/cases/compiler/enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'.
Property 'c' is missing in type 'Ab.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(75,1): error TS2324: Property 'c' is missing in type 'Ab.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'.
Property 'a' is missing in type 'Cd.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'.
tests/cases/compiler/enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'.
Property 'd' is missing in type 'First.E'.
tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2324: Property 'd' is missing in type 'First.E'.
==== tests/cases/compiler/enumAssignmentCompat3.ts (9 errors) ====
==== tests/cases/compiler/enumAssignmentCompat3.ts (11 errors) ====
namespace First {
export enum E {
a, b, c,
@@ -84,8 +82,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.
abc = secondAbc; // ok
abc = secondAbcd; // missing 'd'
~~~
!!! error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'.
!!! error TS2322: Property 'd' is missing in type 'First.E'.
!!! error TS2324: Property 'd' is missing in type 'First.E'.
abc = secondAb; // ok
abc = secondCd; // missing 'd'
~~~
@@ -95,20 +92,22 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.
~~~
!!! error TS2322: Type 'Nope' is not assignable to type 'E'.
abc = decl; // ok
~~~
!!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'.
secondAbc = abc; // ok
secondAbcd = abc; // ok
secondAb = abc; // missing 'c'
~~~~~~~~
!!! error TS2322: Type 'First.E' is not assignable to type 'Ab.E'.
!!! error TS2322: Property 'c' is missing in type 'Ab.E'.
!!! error TS2324: Property 'c' is missing in type 'Ab.E'.
secondCd = abc; // missing 'a' and 'b'
~~~~~~~~
!!! error TS2322: Type 'First.E' is not assignable to type 'Cd.E'.
!!! error TS2322: Property 'a' is missing in type 'Cd.E'.
nope = abc; // nope!
~~~~
!!! error TS2322: Type 'E' is not assignable to type 'Nope'.
decl = abc; // ok
~~~~
!!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'.
// const is only assignable to itself
k = k;
@@ -122,8 +121,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.
// merged enums compare all their members
abc = merged; // missing 'd'
~~~
!!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'.
!!! error TS2322: Property 'd' is missing in type 'First.E'.
!!! error TS2324: Property 'd' is missing in type 'First.E'.
merged = abc; // ok
abc = merged2; // ok
merged2 = abc; // ok
@@ -0,0 +1,30 @@
tests/cases/compiler/enumAssignmentCompat5.ts(20,9): error TS2535: Enum type 'Computed' has members with initializers that are not literals.
==== tests/cases/compiler/enumAssignmentCompat5.ts (1 errors) ====
enum E {
A, B, C
}
enum Computed {
A = 1 << 1,
B = 1 << 2,
C = 1 << 3,
}
let n: number;
let e: E = n; // ok because it's too inconvenient otherwise
e = 0; // ok, in range
e = 4; // ok, out of range, but allowed computed enums don't have all members
let a: E.A = 0; // ok, A === 0
a = 2; // error, 2 !== 0
a = n; // ok
let c: Computed = n; // ok
c = n; // ok
c = 4; // ok
let ca: Computed.A = 1; // error, Computed.A isn't a literal type because Computed has no enum literals
~~~~~~~~~~
!!! error TS2535: Enum type 'Computed' has members with initializers that are not literals.
@@ -0,0 +1,50 @@
//// [enumAssignmentCompat5.ts]
enum E {
A, B, C
}
enum Computed {
A = 1 << 1,
B = 1 << 2,
C = 1 << 3,
}
let n: number;
let e: E = n; // ok because it's too inconvenient otherwise
e = 0; // ok, in range
e = 4; // ok, out of range, but allowed computed enums don't have all members
let a: E.A = 0; // ok, A === 0
a = 2; // error, 2 !== 0
a = n; // ok
let c: Computed = n; // ok
c = n; // ok
c = 4; // ok
let ca: Computed.A = 1; // error, Computed.A isn't a literal type because Computed has no enum literals
//// [enumAssignmentCompat5.js]
var E;
(function (E) {
E[E["A"] = 0] = "A";
E[E["B"] = 1] = "B";
E[E["C"] = 2] = "C";
})(E || (E = {}));
var Computed;
(function (Computed) {
Computed[Computed["A"] = 2] = "A";
Computed[Computed["B"] = 4] = "B";
Computed[Computed["C"] = 8] = "C";
})(Computed || (Computed = {}));
var n;
var e = n; // ok because it's too inconvenient otherwise
e = 0; // ok, in range
e = 4; // ok, out of range, but allowed computed enums don't have all members
var a = 0; // ok, A === 0
a = 2; // error, 2 !== 0
a = n; // ok
var c = n; // ok
c = n; // ok
c = 4; // ok
var ca = 1; // error, Computed.A isn't a literal type because Computed has no enum literals
@@ -0,0 +1,44 @@
tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(24,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'.
tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(25,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'.
tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(26,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'.
tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts(27,7): error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'.
==== tests/cases/compiler/enumLiteralAssignableToEnumInsideUnion.ts (4 errors) ====
module X {
export enum Foo {
A, B
}
}
module Y {
export enum Foo {
A, B
}
}
module Z {
export enum Foo {
A = 1 << 1,
B = 1 << 2,
}
}
module Ka {
export enum Foo {
A = 1 << 10,
B = 1 << 11,
}
}
const e0: X.Foo | boolean = Y.Foo.A; // ok
const e1: X.Foo | boolean = Z.Foo.A; // not legal, Z is computed
~~
!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'.
const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // still not legal
~~
!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo'.
const e3: X.Foo.B | boolean = Z.Foo.A; // not legal
~~
!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.B'.
const e4: X.Foo.A | boolean = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A
~~
!!! error TS2322: Type 'Foo' is not assignable to type 'boolean | Foo.A'.
const e5: Ka.Foo | boolean = Z.Foo.A; // ok
@@ -0,0 +1,70 @@
//// [enumLiteralAssignableToEnumInsideUnion.ts]
module X {
export enum Foo {
A, B
}
}
module Y {
export enum Foo {
A, B
}
}
module Z {
export enum Foo {
A = 1 << 1,
B = 1 << 2,
}
}
module Ka {
export enum Foo {
A = 1 << 10,
B = 1 << 11,
}
}
const e0: X.Foo | boolean = Y.Foo.A; // ok
const e1: X.Foo | boolean = Z.Foo.A; // not legal, Z is computed
const e2: X.Foo.A | X.Foo.B | boolean = Z.Foo.A; // still not legal
const e3: X.Foo.B | boolean = Z.Foo.A; // not legal
const e4: X.Foo.A | boolean = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A
const e5: Ka.Foo | boolean = Z.Foo.A; // ok
//// [enumLiteralAssignableToEnumInsideUnion.js]
var X;
(function (X) {
(function (Foo) {
Foo[Foo["A"] = 0] = "A";
Foo[Foo["B"] = 1] = "B";
})(X.Foo || (X.Foo = {}));
var Foo = X.Foo;
})(X || (X = {}));
var Y;
(function (Y) {
(function (Foo) {
Foo[Foo["A"] = 0] = "A";
Foo[Foo["B"] = 1] = "B";
})(Y.Foo || (Y.Foo = {}));
var Foo = Y.Foo;
})(Y || (Y = {}));
var Z;
(function (Z) {
(function (Foo) {
Foo[Foo["A"] = 2] = "A";
Foo[Foo["B"] = 4] = "B";
})(Z.Foo || (Z.Foo = {}));
var Foo = Z.Foo;
})(Z || (Z = {}));
var Ka;
(function (Ka) {
(function (Foo) {
Foo[Foo["A"] = 1024] = "A";
Foo[Foo["B"] = 2048] = "B";
})(Ka.Foo || (Ka.Foo = {}));
var Foo = Ka.Foo;
})(Ka || (Ka = {}));
var e0 = Y.Foo.A; // ok
var e1 = Z.Foo.A; // not legal, Z is computed
var e2 = Z.Foo.A; // still not legal
var e3 = Z.Foo.A; // not legal
var e4 = Z.Foo.A; // not legal either because Z.Foo is computed and Z.Foo.A is not necessarily assignable to X.Foo.A
var e5 = Z.Foo.A; // ok
@@ -1,12 +1,12 @@
EmitSkipped: false
FileName : tests/cases/fourslash/shims-pp/inputFile1.js
FileName : /tests/cases/fourslash/shims-pp/inputFile1.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
}());
FileName : tests/cases/fourslash/shims-pp/inputFile1.d.ts
FileName : /tests/cases/fourslash/shims-pp/inputFile1.d.ts
declare var x: number;
declare class Bar {
x: string;
@@ -14,14 +14,14 @@ declare class Bar {
}
EmitSkipped: false
FileName : tests/cases/fourslash/shims-pp/inputFile2.js
FileName : /tests/cases/fourslash/shims-pp/inputFile2.js
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
}());
FileName : tests/cases/fourslash/shims-pp/inputFile2.d.ts
FileName : /tests/cases/fourslash/shims-pp/inputFile2.d.ts
declare var x1: string;
declare class Foo {
x: string;
@@ -1,12 +1,12 @@
EmitSkipped: false
FileName : tests/cases/fourslash/shims/inputFile1.js
FileName : /tests/cases/fourslash/shims/inputFile1.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
}());
FileName : tests/cases/fourslash/shims/inputFile1.d.ts
FileName : /tests/cases/fourslash/shims/inputFile1.d.ts
declare var x: number;
declare class Bar {
x: string;
@@ -14,14 +14,14 @@ declare class Bar {
}
EmitSkipped: false
FileName : tests/cases/fourslash/shims/inputFile2.js
FileName : /tests/cases/fourslash/shims/inputFile2.js
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
}());
FileName : tests/cases/fourslash/shims/inputFile2.d.ts
FileName : /tests/cases/fourslash/shims/inputFile2.d.ts
declare var x1: string;
declare class Foo {
x: string;
@@ -1,12 +1,12 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js
var x = 5;
var Bar = (function () {
function Bar() {
}
return Bar;
}());
FileName : tests/cases/fourslash/inputFile1.d.ts
FileName : /tests/cases/fourslash/inputFile1.d.ts
declare var x: number;
declare class Bar {
x: string;
@@ -14,14 +14,14 @@ declare class Bar {
}
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js
var x1 = "hello world";
var Foo = (function () {
function Foo() {
}
return Foo;
}());
FileName : tests/cases/fourslash/inputFile2.d.ts
FileName : /tests/cases/fourslash/inputFile2.d.ts
declare var x1: string;
declare class Foo {
x: string;
@@ -1,5 +1,5 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
var x;
var M = (function () {
function M() {
@@ -1,5 +1,5 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js
var x;
var Foo = (function () {
function Foo() {
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"","sources":["inputFile.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"","sources":["inputFile.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile.js
var x = 109;
var foo = "hello world";
var M = (function () {
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"sourceRootDir/","sources":["inputFile.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js.map
{"version":3,"file":"inputFile.js","sourceRoot":"sourceRootDir/","sources":["inputFile.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile.js
var x = 109;
var foo = "hello world";
var M = (function () {
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"sourceRootDir/","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"sourceRootDir/","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile1.js
var x = 109;
var foo = "hello world";
var M = (function () {
@@ -10,8 +10,8 @@ var M = (function () {
}());
//# sourceMappingURL=inputFile1.js.map
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"sourceRootDir/","sources":["inputFile2.ts"],"names":[],"mappings":"AAAA,IAAI,GAAG,GAAG,wBAAwB,CAAC;AACnC;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"sourceRootDir/","sources":["inputFile2.ts"],"names":[],"mappings":"AAAA,IAAI,GAAG,GAAG,wBAAwB,CAAC;AACnC;IAAA;IAGA,CAAC;IAAD,QAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile2.js
var bar = "hello world Typescript";
var C = (function () {
function C() {
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile1.js
// regular ts file
var t = 5;
var Bar = (function () {
@@ -8,7 +8,7 @@ var Bar = (function () {
}
return Bar;
}());
//# sourceMappingURL=inputFile1.js.mapFileName : tests/cases/fourslash/inputFile1.d.ts
//# sourceMappingURL=inputFile1.js.mapFileName : /tests/cases/fourslash/inputFile1.d.ts
declare var t: number;
declare class Bar {
x: string;
@@ -16,11 +16,11 @@ declare class Bar {
}
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.jsx.map
{"version":3,"file":"inputFile2.jsx","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,EAAG,CAAA"}FileName : tests/cases/fourslash/inputFile2.jsx
FileName : /tests/cases/fourslash/inputFile2.jsx.map
{"version":3,"file":"inputFile2.jsx","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,EAAG,CAAA"}FileName : /tests/cases/fourslash/inputFile2.jsx
var y = "my div";
var x = <div name={y}/>;
//# sourceMappingURL=inputFile2.jsx.mapFileName : tests/cases/fourslash/inputFile2.d.ts
//# sourceMappingURL=inputFile2.jsx.mapFileName : /tests/cases/fourslash/inputFile2.d.ts
declare var y: string;
declare var x: any;
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js.map
{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile1.js
// regular ts file
var t = 5;
var Bar = (function () {
@@ -8,7 +8,7 @@ var Bar = (function () {
}
return Bar;
}());
//# sourceMappingURL=inputFile1.js.mapFileName : tests/cases/fourslash/inputFile1.d.ts
//# sourceMappingURL=inputFile1.js.mapFileName : /tests/cases/fourslash/inputFile1.d.ts
declare var t: number;
declare class Bar {
x: string;
@@ -16,11 +16,11 @@ declare class Bar {
}
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AACA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,qBAAC,GAAG,IAAC,IAAI,EAAG,CAAE,EAAG,CAAA"}FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js.map
{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AACA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,qBAAC,GAAG,IAAC,IAAI,EAAG,CAAE,EAAG,CAAA"}FileName : /tests/cases/fourslash/inputFile2.js
var y = "my div";
var x = React.createElement("div", {name: y});
//# sourceMappingURL=inputFile2.js.mapFileName : tests/cases/fourslash/inputFile2.d.ts
//# sourceMappingURL=inputFile2.js.mapFileName : /tests/cases/fourslash/inputFile2.d.ts
declare var React: any;
declare var y: string;
declare var x: any;
@@ -1,7 +1,7 @@
EmitSkipped: false
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js
var x1 = "hello world";
var Foo = (function () {
function Foo() {
@@ -1,7 +1,7 @@
EmitSkipped: false
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile2.js
FileName : /tests/cases/fourslash/inputFile2.js
"use strict";
var Foo = (function () {
function Foo() {
@@ -11,6 +11,6 @@ var Foo = (function () {
exports.Foo = Foo;
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile3.js
FileName : /tests/cases/fourslash/inputFile3.js
var x = "hello";
@@ -1,5 +1,5 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js
// File contains early errors. All outputs should be skipped.
var uninitialized_const_error;
@@ -1,7 +1,7 @@
EmitSkipped: true
Diagnostics:
Exported variable 'foo' has or is using private name 'C'.
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
var M;
(function (M) {
var C = (function () {
@@ -1,7 +1,7 @@
EmitSkipped: true
Diagnostics:
Exported variable 'foo' has or is using private name 'C'.
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
define(["require", "exports"], function (require, exports) {
"use strict";
var C = (function () {
@@ -1,4 +1,4 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
var x = "hello world";
@@ -1,6 +1,6 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
var x = "hello world";
FileName : tests/cases/fourslash/inputFile.d.ts
FileName : /tests/cases/fourslash/inputFile.d.ts
declare var x: number;
@@ -1,8 +1,8 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js
// File to emit, does not contain semantic errors
// expected to be emitted correctelly regardless of the semantic errors in the other file
var noErrors = true;
FileName : tests/cases/fourslash/inputFile1.d.ts
FileName : /tests/cases/fourslash/inputFile1.d.ts
declare var noErrors: boolean;
@@ -1,5 +1,5 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile1.js
FileName : /tests/cases/fourslash/inputFile1.js
// File to emit, does not contain syntactic errors
// expected to be emitted correctelly regardless of the syntactic errors in the other file
var noErrors = true;
@@ -1,4 +1,4 @@
EmitSkipped: false
FileName : tests/cases/fourslash/inputFile.js
FileName : /tests/cases/fourslash/inputFile.js
var x;
@@ -2,7 +2,7 @@ tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(3,5): erro
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(4,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(9,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(15,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(15,16): error TS7016: Property 'haveOnlySet' implicitly has type 'any', because its 'set' accessor lacks a type annotation.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(15,16): error TS7032: Property 'haveOnlySet' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(15,28): error TS7006: Parameter 'newXValue' implicitly has an 'any' type.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(20,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(20,16): error TS7010: 'haveOnlyGet', which lacks return-type annotation, implicitly has an 'any' return type.
@@ -33,7 +33,7 @@ tests/cases/compiler/implicitAnyGetAndSetAccessorWithAnyReturnType.ts(20,16): er
~~~~~~~~~~~
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
~~~~~~~~~~~
!!! error TS7016: Property 'haveOnlySet' implicitly has type 'any', because its 'set' accessor lacks a type annotation.
!!! error TS7032: Property 'haveOnlySet' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
~~~~~~~~~
!!! error TS7006: Parameter 'newXValue' implicitly has an 'any' type.
}
@@ -0,0 +1,27 @@
tests/cases/compiler/noImplicitAnyMissingGetAccessor.ts(4,25): error TS7032: Property 'message' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
tests/cases/compiler/noImplicitAnyMissingGetAccessor.ts(4,33): error TS7006: Parameter 'str' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyMissingGetAccessor.ts(9,16): error TS7032: Property 'message' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
tests/cases/compiler/noImplicitAnyMissingGetAccessor.ts(9,24): error TS7006: Parameter 'str' implicitly has an 'any' type.
==== tests/cases/compiler/noImplicitAnyMissingGetAccessor.ts (4 errors) ====
abstract class Parent
{
public abstract set message(str);
~~~~~~~
!!! error TS7032: Property 'message' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
~~~
!!! error TS7006: Parameter 'str' implicitly has an 'any' type.
}
class Child extends Parent {
_x: any;
public set message(str) {
~~~~~~~
!!! error TS7032: Property 'message' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
~~~
!!! error TS7006: Parameter 'str' implicitly has an 'any' type.
this._x = str;
}
}
@@ -0,0 +1,44 @@
//// [noImplicitAnyMissingGetAccessor.ts]
abstract class Parent
{
public abstract set message(str);
}
class Child extends Parent {
_x: any;
public set message(str) {
this._x = str;
}
}
//// [noImplicitAnyMissingGetAccessor.js]
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Parent = (function () {
function Parent() {
}
Object.defineProperty(Parent.prototype, "message", {
set: function (str) { },
enumerable: true,
configurable: true
});
return Parent;
}());
var Child = (function (_super) {
__extends(Child, _super);
function Child() {
_super.apply(this, arguments);
}
Object.defineProperty(Child.prototype, "message", {
set: function (str) {
this._x = str;
},
enumerable: true,
configurable: true
});
return Child;
}(Parent));
@@ -0,0 +1,17 @@
tests/cases/compiler/noImplicitAnyMissingSetAccessor.ts(4,25): error TS7033: Property 'message' implicitly has type 'any', because its get accessor lacks a return type annotation.
==== tests/cases/compiler/noImplicitAnyMissingSetAccessor.ts (1 errors) ====
abstract class Parent
{
public abstract get message();
~~~~~~~
!!! error TS7033: Property 'message' implicitly has type 'any', because its get accessor lacks a return type annotation.
}
class Child extends Parent {
public get message() {
return "";
}
}
@@ -0,0 +1,43 @@
//// [noImplicitAnyMissingSetAccessor.ts]
abstract class Parent
{
public abstract get message();
}
class Child extends Parent {
public get message() {
return "";
}
}
//// [noImplicitAnyMissingSetAccessor.js]
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Parent = (function () {
function Parent() {
}
Object.defineProperty(Parent.prototype, "message", {
get: function () { },
enumerable: true,
configurable: true
});
return Parent;
}());
var Child = (function (_super) {
__extends(Child, _super);
function Child() {
_super.apply(this, arguments);
}
Object.defineProperty(Child.prototype, "message", {
get: function () {
return "";
},
enumerable: true,
configurable: true
});
return Child;
}(Parent));
@@ -0,0 +1,14 @@
//// [numberAssignableToEnumInsideUnion.ts]
enum E { A, B }
let n: number;
let z: E | boolean = n;
//// [numberAssignableToEnumInsideUnion.js]
var E;
(function (E) {
E[E["A"] = 0] = "A";
E[E["B"] = 1] = "B";
})(E || (E = {}));
var n;
var z = n;
@@ -0,0 +1,14 @@
=== tests/cases/compiler/numberAssignableToEnumInsideUnion.ts ===
enum E { A, B }
>E : Symbol(E, Decl(numberAssignableToEnumInsideUnion.ts, 0, 0))
>A : Symbol(E.A, Decl(numberAssignableToEnumInsideUnion.ts, 0, 8))
>B : Symbol(E.B, Decl(numberAssignableToEnumInsideUnion.ts, 0, 11))
let n: number;
>n : Symbol(n, Decl(numberAssignableToEnumInsideUnion.ts, 1, 3))
let z: E | boolean = n;
>z : Symbol(z, Decl(numberAssignableToEnumInsideUnion.ts, 2, 3))
>E : Symbol(E, Decl(numberAssignableToEnumInsideUnion.ts, 0, 0))
>n : Symbol(n, Decl(numberAssignableToEnumInsideUnion.ts, 1, 3))
@@ -0,0 +1,14 @@
=== tests/cases/compiler/numberAssignableToEnumInsideUnion.ts ===
enum E { A, B }
>E : E
>A : E
>B : E
let n: number;
>n : number
let z: E | boolean = n;
>z : boolean | E
>E : E
>n : number
@@ -1,8 +1,5 @@
tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(4,43): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'.
Object literal may only specify known properties, and 'name' does not exist in type '{ b: string; id: number; }'.
tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,16): error TS1131: Property or signature expected.
tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,22): error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'.
tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(5,25): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(6,79): error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ id: string; name: number; }'.
Types of property 'id' are incompatible.
Type 'number' is not assignable to type 'string'.
@@ -11,7 +8,7 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr
Type 'number' is not assignable to type 'boolean'.
==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts (6 errors) ====
==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts (3 errors) ====
var id: number = 10000;
var name: string = "my name";
@@ -19,13 +16,7 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr
~~~~
!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ b: string; id: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'name' does not exist in type '{ b: string; id: number; }'.
var person1: { name, id }; // error: can't use short-hand property assignment in type position
~~~~
!!! error TS1131: Property or signature expected.
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'id' must be of type 'number', but here has type 'any'.
~
!!! error TS1128: Declaration or statement expected.
var person1: { name, id }; // ok
function foo(name: string, id: number): { id: string, name: number } { return { name, id }; } // error
~~~~~~~~~~~~
!!! error TS2322: Type '{ name: string; id: number; }' is not assignable to type '{ id: string; name: number; }'.

Some files were not shown because too many files have changed in this diff Show More