Merge branch 'master' into FixAbsoluteTripleSlashCompletions

This commit is contained in:
Arthur Ozga
2016-10-03 11:07:41 -07:00
19 changed files with 323 additions and 41 deletions

View File

@@ -5,7 +5,6 @@
"removeComments": true,
"preserveConstEnums": true,
"pretty": true,
"outDir": "../../../built/local",
"module": "commonjs",
"sourceMap": true,
"stripInternal": true,

View File

@@ -93,6 +93,7 @@ namespace ts.server {
export const Geterr = "geterr";
export const GeterrForProject = "geterrForProject";
export const Implementation = "implementation";
export const ImplementationFull = "implementation-full";
export const SemanticDiagnosticsSync = "semanticDiagnosticsSync";
export const SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
export const NavBar = "navbar";
@@ -421,7 +422,7 @@ namespace ts.server {
});
}
private getImplementation(args: protocol.FileLocationRequestArgs): protocol.FileSpan[] {
private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.FileSpan[] | ImplementationLocation[] {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
@@ -429,11 +430,16 @@ namespace ts.server {
if (!implementations) {
return [];
}
return implementations.map(impl => ({
file: impl.fileName,
start: scriptInfo.positionToLineOffset(impl.textSpan.start),
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(impl.textSpan))
}));
if (simplifiedResult) {
return implementations.map(impl => ({
file: impl.fileName,
start: scriptInfo.positionToLineOffset(impl.textSpan.start),
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(impl.textSpan))
}));
}
else {
return implementations;
}
}
private getOccurrences(args: protocol.FileLocationRequestArgs): protocol.OccurrencesResponseItem[] {
@@ -1329,7 +1335,10 @@ namespace ts.server {
return this.requiredResponse(this.getTypeDefinition(request.arguments));
},
[CommandNames.Implementation]: (request: protocol.Request) => {
return this.requiredResponse(this.getImplementation(request.arguments));
return this.requiredResponse(this.getImplementation(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.ImplementationFull]: (request: protocol.Request) => {
return this.requiredResponse(this.getImplementation(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.References]: (request: protocol.FileLocationRequest) => {
return this.requiredResponse(this.getReferences(request.arguments, /*simplifiedResult*/ true));

View File

@@ -5,7 +5,7 @@
"removeComments": true,
"preserveConstEnums": true,
"pretty": true,
"out": "../../built/local/tsserver.js",
"outFile": "../../built/local/tsserver.js",
"sourceMap": true,
"stripInternal": true,
"types": [

View File

@@ -3,7 +3,7 @@
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"out": "../../built/local/tsserverlibrary.js",
"outFile": "../../built/local/tsserverlibrary.js",
"sourceMap": true,
"stripInternal": true,
"declaration": true,

View File

@@ -5,7 +5,7 @@
"removeComments": true,
"preserveConstEnums": true,
"pretty": true,
"out": "../../built/local/typingsInstaller.js",
"outFile": "../../../built/local/typingsInstaller.js",
"sourceMap": true,
"stripInternal": true,
"types": [

View File

@@ -23,6 +23,43 @@ namespace ts.server.typingsInstaller {
return result.resolvedModule && result.resolvedModule.resolvedFileName;
}
export enum PackageNameValidationResult {
Ok,
ScopedPackagesNotSupported,
NameTooLong,
NameStartsWithDot,
NameStartsWithUnderscore,
NameContainsNonURISafeCharacters
}
export const MaxPackageNameLength = 214;
/**
* Validates package name using rules defined at https://docs.npmjs.com/files/package.json
*/
export function validatePackageName(packageName: string): PackageNameValidationResult {
Debug.assert(!!packageName, "Package name is not specified");
if (packageName.length > MaxPackageNameLength) {
return PackageNameValidationResult.NameTooLong;
}
if (packageName.charCodeAt(0) === CharacterCodes.dot) {
return PackageNameValidationResult.NameStartsWithDot;
}
if (packageName.charCodeAt(0) === CharacterCodes._) {
return PackageNameValidationResult.NameStartsWithUnderscore;
}
// check if name is scope package like: starts with @ and has one '/' in the middle
// scoped packages are not currently supported
// TODO: when support will be added we'll need to split and check both scope and package name
if (/^@[^/]+\/[^/]+$/.test(packageName)) {
return PackageNameValidationResult.ScopedPackagesNotSupported;
}
if (encodeURIComponent(packageName) !== packageName) {
return PackageNameValidationResult.NameContainsNonURISafeCharacters;
}
return PackageNameValidationResult.Ok;
}
export const NpmViewRequest: "npm view" = "npm view";
export const NpmInstallRequest: "npm install" = "npm install";
@@ -185,14 +222,54 @@ namespace ts.server.typingsInstaller {
this.knownCachesSet[cacheLocation] = true;
}
private filterTypings(typingsToInstall: string[]) {
if (typingsToInstall.length === 0) {
return typingsToInstall;
}
const result: string[] = [];
for (const typing of typingsToInstall) {
if (this.missingTypingsSet[typing]) {
continue;
}
const validationResult = validatePackageName(typing);
if (validationResult === PackageNameValidationResult.Ok) {
result.push(typing);
}
else {
// add typing name to missing set so we won't process it again
this.missingTypingsSet[typing] = true;
if (this.log.isEnabled()) {
switch (validationResult) {
case PackageNameValidationResult.NameTooLong:
this.log.writeLine(`Package name '${typing}' should be less than ${MaxPackageNameLength} characters`);
break;
case PackageNameValidationResult.NameStartsWithDot:
this.log.writeLine(`Package name '${typing}' cannot start with '.'`);
break;
case PackageNameValidationResult.NameStartsWithUnderscore:
this.log.writeLine(`Package name '${typing}' cannot start with '_'`);
break;
case PackageNameValidationResult.ScopedPackagesNotSupported:
this.log.writeLine(`Package '${typing}' is scoped and currently is not supported`);
break;
case PackageNameValidationResult.NameContainsNonURISafeCharacters:
this.log.writeLine(`Package name '${typing}' contains non URI safe characters`);
break;
}
}
}
}
return result;
}
private installTypings(req: DiscoverTypings, cachePath: string, currentlyCachedTypings: string[], typingsToInstall: string[]) {
if (this.log.isEnabled()) {
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
}
typingsToInstall = filter(typingsToInstall, x => !this.missingTypingsSet[x]);
typingsToInstall = this.filterTypings(typingsToInstall);
if (typingsToInstall.length === 0) {
if (this.log.isEnabled()) {
this.log.writeLine(`All typings are known to be missing - no need to go any further`);
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
}
return;
}