fix merge issues, restore tests

This commit is contained in:
Vladimir Matveev
2016-09-27 14:02:10 -07:00
parent 912e685f2a
commit 9c0e64d443
11 changed files with 97 additions and 473 deletions

View File

@@ -1,5 +1,4 @@
/// <reference path="utilities.ts"/>
/// <reference path="moduleNameResolver.ts"/>
/// <reference path="parser.ts"/>
/* @internal */

View File

@@ -1,3 +1,4 @@
/// <reference path="moduleNameResolver.ts"/>
/// <reference path="binder.ts"/>
/* @internal */

View File

@@ -1889,6 +1889,78 @@ namespace ts {
: ((fileName) => fileName.toLowerCase());
}
/**
* patternStrings contains both pattern strings (containing "*") and regular strings.
* Return an exact match if possible, or a pattern match, or undefined.
* (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
*/
/* @internal */
export function matchPatternOrExact(patternStrings: string[], candidate: string): string | Pattern | undefined {
const patterns: Pattern[] = [];
for (const patternString of patternStrings) {
const pattern = tryParsePattern(patternString);
if (pattern) {
patterns.push(pattern);
}
else if (patternString === candidate) {
// pattern was matched as is - no need to search further
return patternString;
}
}
return findBestPatternMatch(patterns, _ => _, candidate);
}
/* @internal */
export function patternText({prefix, suffix}: Pattern): string {
return `${prefix}*${suffix}`;
}
/**
* Given that candidate matches pattern, returns the text matching the '*'.
* E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
*/
/* @internal */
export function matchedText(pattern: Pattern, candidate: string): string {
Debug.assert(isPatternMatch(pattern, candidate));
return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
}
/** Return the object corresponding to the best pattern to match `candidate`. */
/* @internal */
export function findBestPatternMatch<T>(values: T[], getPattern: (value: T) => Pattern, candidate: string): T | undefined {
let matchedValue: T | undefined = undefined;
// use length of prefix as betterness criteria
let longestMatchPrefixLength = -1;
for (const v of values) {
const pattern = getPattern(v);
if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
longestMatchPrefixLength = pattern.prefix.length;
matchedValue = v;
}
}
return matchedValue;
}
function isPatternMatch({prefix, suffix}: Pattern, candidate: string) {
return candidate.length >= prefix.length + suffix.length &&
startsWith(candidate, prefix) &&
endsWith(candidate, suffix);
}
/* @internal */
export function tryParsePattern(pattern: string): Pattern | undefined {
// This should be verified outside of here and a proper error thrown.
Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
const indexOfStar = pattern.indexOf("*");
return indexOfStar === -1 ? undefined : {
prefix: pattern.substr(0, indexOfStar),
suffix: pattern.substr(indexOfStar + 1)
};
}
export function positionIsSynthesized(pos: number): boolean {
// This is a fast way of testing the following conditions:
// pos === undefined || pos === null || isNaN(pos) || pos < 0;

View File

@@ -13,6 +13,9 @@ namespace ts {
_i = 0x10000000, // Use/preference flag for '_i'
}
const id = (s: SourceFile) => s;
const nullTransformers: Transformer[] = [ctx => id];
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
const delimiters = createDelimiterMap();
@@ -192,7 +195,7 @@ const _super = (function (geti, seti) {
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
const emitterDiagnostics = createDiagnosticCollection();
const newLine = host.getNewLine();
const transformers = getTransformers(compilerOptions);
const transformers: Transformer[] = emitOnlyDtsFiles ? nullTransformers : getTransformers(compilerOptions);
const writer = createTextWriter(newLine);
const {
write,
@@ -271,7 +274,9 @@ const _super = (function (geti, seti) {
function emitFile(jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
// Make sure not to write js file and source map file if any of them cannot be written
if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) {
printFile(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
if (!emitOnlyDtsFiles) {
printFile(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
}
}
else {
emitSkipped = true;
@@ -282,7 +287,9 @@ const _super = (function (geti, seti) {
}
if (!emitSkipped && emittedFilesList) {
emittedFilesList.push(jsFilePath);
if (!emitOnlyDtsFiles) {
emittedFilesList.push(jsFilePath);
}
if (sourceMapFilePath) {
emittedFilesList.push(sourceMapFilePath);
}

View File

@@ -512,75 +512,6 @@ namespace ts {
}
}
/**
* patternStrings contains both pattern strings (containing "*") and regular strings.
* Return an exact match if possible, or a pattern match, or undefined.
* (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
*/
function matchPatternOrExact(patternStrings: string[], candidate: string): string | Pattern | undefined {
const patterns: Pattern[] = [];
for (const patternString of patternStrings) {
const pattern = tryParsePattern(patternString);
if (pattern) {
patterns.push(pattern);
}
else if (patternString === candidate) {
// pattern was matched as is - no need to search further
return patternString;
}
}
return findBestPatternMatch(patterns, _ => _, candidate);
}
function patternText({prefix, suffix}: Pattern): string {
return `${prefix}*${suffix}`;
}
/**
* Given that candidate matches pattern, returns the text matching the '*'.
* E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
*/
function matchedText(pattern: Pattern, candidate: string): string {
Debug.assert(isPatternMatch(pattern, candidate));
return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
}
/** Return the object corresponding to the best pattern to match `candidate`. */
/* @internal */
export function findBestPatternMatch<T>(values: T[], getPattern: (value: T) => Pattern, candidate: string): T | undefined {
let matchedValue: T | undefined = undefined;
// use length of prefix as betterness criteria
let longestMatchPrefixLength = -1;
for (const v of values) {
const pattern = getPattern(v);
if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
longestMatchPrefixLength = pattern.prefix.length;
matchedValue = v;
}
}
return matchedValue;
}
function isPatternMatch({prefix, suffix}: Pattern, candidate: string) {
return candidate.length >= prefix.length + suffix.length &&
startsWith(candidate, prefix) &&
endsWith(candidate, suffix);
}
/* @internal */
export function tryParsePattern(pattern: string): Pattern | undefined {
// This should be verified outside of here and a proper error thrown.
Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
const indexOfStar = pattern.indexOf("*");
return indexOfStar === -1 ? undefined : {
prefix: pattern.substr(0, indexOfStar),
suffix: pattern.substr(indexOfStar + 1)
};
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
const containingDirectory = getDirectoryPath(containingFile);
const supportedExtensions = getSupportedExtensions(compilerOptions);

View File

@@ -945,6 +945,8 @@ namespace ts {
let program: Program;
let lastProjectVersion: string;
let lastTypesRootVersion = 0;
const useCaseSensitivefileNames = false;
const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
@@ -993,6 +995,13 @@ namespace ts {
}
}
const typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0;
if (lastTypesRootVersion !== typeRootsVersion) {
log("TypeRoots version has changed; provide new program");
program = undefined;
lastTypesRootVersion = typeRootsVersion;
}
// Get a fresh cache of the host information
let hostCache = new HostCache(host, getCanonicalFileName);

View File

@@ -148,6 +148,11 @@ namespace ts {
readFile?(path: string, encoding?: string): string;
fileExists?(path: string): boolean;
/*
* LS host can optionally implement these methods to support automatic updating when new type libraries are installed
*/
getTypeRootsVersion?(): number;
/*
* 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