Skip to content

Commit d052bb8

Browse files
author
Andy
authored
Add project telemetry (#16050)
* Add project telemetry * Respond to some PR comments * Wrap event in a TelemetryEvent payload * Replace paths with empty string instead of removing them entirely * Add "version" property to payload * Add telemetry for typeAcquisition settings * Add "files", "include", "exclude", and "compileOnSave" * Convert typingsOptions include and exclude to booleanss * Add "extends", "configFileName", and "projectType" * configFileName: Use "other" instead of undefined * Add "languageServiceEnabled" telemetry
1 parent 7cca4ba commit d052bb8

11 files changed

+505
-36
lines changed

Jakefile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ var harnessSources = harnessCoreSources.concat([
129129
"initializeTSConfig.ts",
130130
"printer.ts",
131131
"textChanges.ts",
132+
"telemetry.ts",
132133
"transform.ts",
133134
"customTransforms.ts",
134135
].map(function (f) {

src/compiler/commandLineParser.ts

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,7 @@ namespace ts {
692692
return typeAcquisition;
693693
}
694694

695-
/* @internal */
696-
export function getOptionNameMap(): OptionNameMap {
695+
function getOptionNameMap(): OptionNameMap {
697696
if (optionNameMapCache) {
698697
return optionNameMapCache;
699698
}
@@ -746,7 +745,6 @@ namespace ts {
746745
const options: CompilerOptions = {};
747746
const fileNames: string[] = [];
748747
const errors: Diagnostic[] = [];
749-
const { optionNameMap, shortOptionNames } = getOptionNameMap();
750748

751749
parseStrings(commandLine);
752750
return {
@@ -758,21 +756,13 @@ namespace ts {
758756
function parseStrings(args: string[]) {
759757
let i = 0;
760758
while (i < args.length) {
761-
let s = args[i];
759+
const s = args[i];
762760
i++;
763761
if (s.charCodeAt(0) === CharacterCodes.at) {
764762
parseResponseFile(s.slice(1));
765763
}
766764
else if (s.charCodeAt(0) === CharacterCodes.minus) {
767-
s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase();
768-
769-
// Try to translate short option names to their full equivalents.
770-
const short = shortOptionNames.get(s);
771-
if (short !== undefined) {
772-
s = short;
773-
}
774-
775-
const opt = optionNameMap.get(s);
765+
const opt = getOptionFromName(s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
776766
if (opt) {
777767
if (opt.isTSConfigOnly) {
778768
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
@@ -860,6 +850,19 @@ namespace ts {
860850
}
861851
}
862852

853+
function getOptionFromName(optionName: string, allowShort = false): CommandLineOption | undefined {
854+
optionName = optionName.toLowerCase();
855+
const { optionNameMap, shortOptionNames } = getOptionNameMap();
856+
// Try to translate short option names to their full equivalents.
857+
if (allowShort) {
858+
const short = shortOptionNames.get(optionName);
859+
if (short !== undefined) {
860+
optionName = short;
861+
}
862+
}
863+
return optionNameMap.get(optionName);
864+
}
865+
863866
/**
864867
* Read tsconfig.json file
865868
* @param fileName The path to the config file
@@ -1705,4 +1708,42 @@ namespace ts {
17051708
function caseInsensitiveKeyMapper(key: string) {
17061709
return key.toLowerCase();
17071710
}
1711+
1712+
/**
1713+
* Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed.
1714+
* Also converts enum values back to strings.
1715+
*/
1716+
/* @internal */
1717+
export function convertCompilerOptionsForTelemetry(opts: ts.CompilerOptions): ts.CompilerOptions {
1718+
const out: ts.CompilerOptions = {};
1719+
for (const key in opts) if (opts.hasOwnProperty(key)) {
1720+
const type = getOptionFromName(key);
1721+
if (type !== undefined) { // Ignore unknown options
1722+
out[key] = getOptionValueWithEmptyStrings(opts[key], type);
1723+
}
1724+
}
1725+
return out;
1726+
}
1727+
1728+
function getOptionValueWithEmptyStrings(value: any, option: CommandLineOption): {} {
1729+
switch (option.type) {
1730+
case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "".
1731+
return "";
1732+
case "string": // Could be any arbitrary string -- use empty string instead.
1733+
return "";
1734+
case "number": // Allow numbers, but be sure to check it's actually a number.
1735+
return typeof value === "number" ? value : "";
1736+
case "boolean":
1737+
return typeof value === "boolean" ? value : "";
1738+
case "list":
1739+
const elementType = (option as CommandLineOptionOfListType).element;
1740+
return ts.isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : "";
1741+
default:
1742+
return ts.forEachEntry(option.type, (optionEnumValue, optionStringValue) => {
1743+
if (optionEnumValue === value) {
1744+
return optionStringValue;
1745+
}
1746+
});
1747+
}
1748+
}
17081749
}

src/compiler/core.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,18 @@ namespace ts {
521521
return result || array;
522522
}
523523

524+
export function mapDefined<T>(array: ReadonlyArray<T>, mapFn: (x: T, i: number) => T | undefined): ReadonlyArray<T> {
525+
const result: T[] = [];
526+
for (let i = 0; i < array.length; i++) {
527+
const item = array[i];
528+
const mapped = mapFn(item, i);
529+
if (mapped !== undefined) {
530+
result.push(mapped);
531+
}
532+
}
533+
return result;
534+
}
535+
524536
/**
525537
* Computes the first matching span of elements and returns a tuple of the first span
526538
* and the remaining elements.

src/harness/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
"./unittests/printer.ts",
128128
"./unittests/transform.ts",
129129
"./unittests/customTransforms.ts",
130-
"./unittests/textChanges.ts"
130+
"./unittests/textChanges.ts",
131+
"./unittests/telemetry.ts"
131132
]
132133
}

0 commit comments

Comments
 (0)