Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint extensions #10162

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
completedDts.pipe(clone())
.pipe(insert.transform((content, file) => {
file.path = nodeStandaloneDefinitionsFile;
return content.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
return content.replace(/declare (namespace|module) ts {/g, 'declare module "typescript" {\n import * as ts from "typescript";');
}))
]).pipe(gulp.dest(builtLocalDirectory));
});
Expand Down
7 changes: 5 additions & 2 deletions Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var compilerSources = [
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
"extensions.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
Expand All @@ -67,6 +68,7 @@ var servicesSources = [
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
"extensions.ts",
"commandLineParser.ts",
"diagnosticInformationMap.generated.ts"
].map(function (f) {
Expand Down Expand Up @@ -131,6 +133,7 @@ var harnessCoreSources = [
"typeWriter.ts",
"fourslashRunner.ts",
"projectsRunner.ts",
"extensionRunner.ts",
"loggedIO.ts",
"rwcRunner.ts",
"test262Runner.ts",
Expand Down Expand Up @@ -158,7 +161,7 @@ var harnessSources = harnessCoreSources.concat([
"convertCompilerOptionsFromJson.ts",
"convertTypingOptionsFromJson.ts",
"tsserverProjectSystem.ts",
"matchFiles.ts"
"matchFiles.ts",
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
Expand Down Expand Up @@ -524,7 +527,7 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca

// Node package definition file to be distributed without the package. Created by replacing
// 'ts' namespace with '"typescript"' as a module.
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts {/g, 'declare module "typescript" {\n import * as ts from "typescript";');
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
});

Expand Down
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17948,9 +17948,9 @@ namespace ts {
return getTypeOfSymbol(symbol);
}

if (isDeclarationName(node)) {
if (isDeclarationName(node) || node.kind === SyntaxKind.SourceFile) {
const symbol = getSymbolAtLocation(node);
return symbol && getTypeOfSymbol(symbol);
return symbol && getTypeOfSymbol(symbol) || unknownType;
}

if (isBindingPattern(node)) {
Expand Down
8 changes: 7 additions & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ namespace ts {
experimental: true,
description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
},
{
name: "extensions",
type: "object",
isTSConfigOnly: true,
description: Diagnostics.List_of_compiler_extensions_to_require
},
{
name: "moduleResolution",
type: {
Expand Down Expand Up @@ -429,7 +435,7 @@ namespace ts {
name: "strictNullChecks",
type: "boolean",
description: Diagnostics.Enable_strict_null_checks
}
},
];

/* @internal */
Expand Down
90 changes: 78 additions & 12 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
/// <reference path="performance.ts" />


namespace ts {
export function startsWith(str: string, prefix: string): boolean {
return str.lastIndexOf(prefix, 0) === 0;
}

export function endsWith(str: string, suffix: string): boolean {
const expectedPos = str.length - suffix.length;
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
}
}

/* @internal */
namespace ts {
/**
Expand Down Expand Up @@ -178,6 +189,26 @@ namespace ts {
return array1.concat(array2);
}

export function flatten<T>(array1: T[][]): T[] {
if (!array1 || !array1.length) return <any>array1;
return [].concat(...array1);
}

export function groupBy<T>(array: T[], classifier: (item: T) => string): {[index: string]: T[]};
export function groupBy<T>(array: T[], classifier: (item: T) => number): {[index: number]: T[]};
export function groupBy<T>(array: T[], classifier: (item: T) => (string | number)): {[index: string]: T[], [index: number]: T[]} {
if (!array || !array.length) return undefined;
const ret: {[index: string]: T[], [index: number]: T[]} = {};
for (const elem of array) {
const key = classifier(elem);
if (!ret[key]) {
ret[key] = [];
}
ret[key].push(elem);
}
return ret;
}

export function deduplicate<T>(array: T[], areEqual?: (a: T, b: T) => boolean): T[] {
let result: T[];
if (array) {
Expand Down Expand Up @@ -908,17 +939,6 @@ namespace ts {
return true;
}

/* @internal */
export function startsWith(str: string, prefix: string): boolean {
return str.lastIndexOf(prefix, 0) === 0;
}

/* @internal */
export function endsWith(str: string, suffix: string): boolean {
const expectedPos = str.length - suffix.length;
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
}

export function fileExtensionIs(path: string, extension: string): boolean {
return path.length > extension.length && endsWith(path, extension);
}
Expand Down Expand Up @@ -1195,7 +1215,8 @@ namespace ts {
export const supportedJavascriptExtensions = [".js", ".jsx"];
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);

export function getSupportedExtensions(options?: CompilerOptions): string[] {
export function getSupportedExtensions(options?: CompilerOptions, loadJS?: boolean): string[] {
if (loadJS) return supportedJavascriptExtensions;
return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
}

Expand Down Expand Up @@ -1373,4 +1394,49 @@ namespace ts {
: ((fileName) => fileName.toLowerCase());
}

/**
* This isn't the strictest deep equal, but it's good enough for us
* - +0 === -0 (though who really wants to consider them different?)
* - arguments and arrays can be equal (both typeof === object, both have enumerable keys)
* - doesn't inspect es6 iterables (not that they're used in this code base)
* - doesn't inspect regex toString value (so only references to the same regex are equal)
* - doesn't inspect date primitive number value (so only references to the same date are equal)
*/
export function deepEqual(a: any, b: any, memo?: [any, any][]): boolean {
if (a === b) return true;
if (typeof a !== typeof b) return false;
// Special case NaN
if (typeof a === "number" && isNaN(a) && isNaN(b)) return true;
// We can't know if function arguments are deep equal, so we say they're equal if they look alike
if (typeof a === "object" || typeof a === "function") {
if (memo) {
for (let i = 0; i < memo.length; i++) {
if (memo[i][0] === a && memo[i][1] === b) return true;
if (memo[i][0] === b && memo[i][1] === a) return true;
}
}
else {
memo = [];
}

const aKeys = ts.getKeys(a);
const bKeys = ts.getKeys(b);
aKeys.sort();
bKeys.sort();

if (aKeys.length !== bKeys.length) return false;

for (let i = 0; i < aKeys.length; i++) {
if (aKeys[i] !== bKeys[i]) return false;
}

memo.push([a, b]);

for (const key of aKeys) {
if (!deepEqual(a[key], b[key], memo)) return false;
}
return true;
}
return false;
}
}
18 changes: 14 additions & 4 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2676,7 +2676,7 @@
"category": "Message",
"code": 6099
},
"'package.json' does not have 'types' field.": {
"'package.json' does not have '{0}' field.": {
"category": "Message",
"code": 6100
},
Expand All @@ -2696,7 +2696,7 @@
"category": "Message",
"code": 6104
},
"Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.": {
"Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": {
"category": "Message",
"code": 6105
},
Expand Down Expand Up @@ -2824,10 +2824,20 @@
"category": "Message",
"code": 6136
},
"No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'": {

"List of compiler extensions to require.": {
"category": "Message",
"code": 6137
"code": 6150
},
"Extension loading failed with error '{0}'.": {
"category": "Error",
"code": 6151
},
"Extension '{0}' exported member '{1}' has extension kind '{2}', but was type '{3}' when type '{4}' was expected.": {
"category": "Error",
"code": 6152
},

"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down
Loading