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

6974 add lib implementation #7715

Merged
merged 23 commits into from
Mar 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
168118f
Modularize ES6 and ES7 library files
Feb 6, 2016
3fef5ba
Implement --lib flag in the compiler and harness
Mar 28, 2016
623eef6
Update unittest for --lib
Mar 28, 2016
f052e90
Update fourslash tests
Mar 28, 2016
eff81b9
Add compiler-baseline tests and associated baselines for --lib flag
Mar 28, 2016
4e6cef2
Addres PR: change lib filenames from es6 to es2015 and es7 to es2016
Mar 28, 2016
7e1470d
Address PR: use getDefaultLibLocation? insteadof getUserDefinedLibFil…
Mar 28, 2016
15367e7
Clean up library files
Mar 28, 2016
7f8774f
Update the baselines for modularize library
Mar 28, 2016
99f9efb
Address PR: give default value for getDefaultLibrarySourceFile and us…
Mar 28, 2016
de7e9f0
Update baselines affected by modularize library PR
Mar 29, 2016
ced3033
Address PR: remove debugger statement
Mar 29, 2016
41a95b7
Address PR: add comment
Mar 29, 2016
41265c7
Address PR: merge two functions to get-default-library-file
Mar 30, 2016
ade9287
Address PR: merge two functions to get-default-library-file
Mar 30, 2016
b9cd882
Address PR: use getDefaultLibLocation to get directory
Mar 30, 2016
327a51b
Address PR: Put --lip options into one line
Mar 30, 2016
1bc5749
Merge branch '6974AddLibSymbolBaselinesUpdate' into 6974AddLibImpleme…
Mar 30, 2016
0ba4a2c
Fix style and whitespace
Mar 30, 2016
56dcd02
Merge branch '6974AddLibImplementation' of https://github.com/Microso…
Mar 30, 2016
992b4f9
Fix test failure by having correct case for the file-name
Mar 30, 2016
fd5c9bd
Fix test failure by having correct case for the file-name
Mar 30, 2016
1490547
Merge branch '6974AddLibImplementation' of https://github.com/Microso…
Mar 30, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
55 changes: 45 additions & 10 deletions Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,53 @@ var harnessSources = harnessCoreSources.concat([
return path.join(serverDirectory, f);
}));

var librarySourceMap = [
{ target: "lib.core.d.ts", sources: ["header.d.ts", "core.d.ts"] },
{ target: "lib.dom.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "dom.generated.d.ts"], },
{ target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "webworker.generated.d.ts"], },
{ target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"], },
{ target: "lib.d.ts", sources: ["header.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], },
{ target: "lib.core.es6.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts"]},
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es6.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] },
{ target: "lib.core.es7.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts", "es7.d.ts"]},
{ target: "lib.es7.d.ts", sources: ["header.d.ts", "es6.d.ts", "es7.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }
var es2015LibrarySources = [
"es2015.array.d.ts",
"es2015.collection.d.ts",
"es2015.function.d.ts",
"es2015.generator.d.ts",
"es2015.iterable.d.ts",
"es2015.math.d.ts",
"es2015.number.d.ts",
"es2015.object.d.ts",
"es2015.promise.d.ts",
"es2015.proxy.d.ts",
"es2015.reflect.d.ts",
"es2015.regexp.d.ts",
"es2015.string.d.ts",
"es2015.symbol.d.ts",
"es2015.symbol.wellknown.d.ts",
];

var es2015LibrarySourceMap = es2015LibrarySources.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});

var es2016LibrarySource = [ "es2016.array.include.d.ts" ];

var es2016LibrarySourceMap = es2016LibrarySource.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
})

var hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"]

var librarySourceMap = [
// Host library
{ target: "lib.dom.d.ts", sources: ["header.d.ts", "dom.generated.d.ts"], },
{ target: "lib.dom.iterable.d.ts", sources: ["header.d.ts", "dom.iterable.d.ts"], },
{ target: "lib.webworker.d.ts", sources: ["header.d.ts", "webworker.generated.d.ts"], },
{ target: "lib.scripthost.d.ts", sources: ["header.d.ts", "scripthost.d.ts"], },

// JavaScript library
{ target: "lib.es5.d.ts", sources: ["header.d.ts", "es5.d.ts"] },
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },

// JavaScript + all host library
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources), },
{ target: "lib.full.es2015.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources), },
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap);

var libraryTargets = librarySourceMap.map(function (f) {
return path.join(builtLocalDirectory, f.target);
});
Expand Down
67 changes: 31 additions & 36 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ namespace ts {

const globals: SymbolTable = {};

let globalESSymbolConstructorSymbol: Symbol;
let getGlobalESSymbolConstructorSymbol: () => Symbol;

let getGlobalPromiseConstructorSymbol: () => Symbol;

Expand All @@ -150,14 +150,19 @@ namespace ts {
let globalNumberType: ObjectType;
let globalBooleanType: ObjectType;
let globalRegExpType: ObjectType;
let globalTemplateStringsArrayType: ObjectType;
let globalESSymbolType: ObjectType;
let globalIterableType: GenericType;
let globalIteratorType: GenericType;
let globalIterableIteratorType: GenericType;

let anyArrayType: Type;
let anyReadonlyArrayType: Type;

// The library files are only loaded when the feature is used.
// This allows users to just specify library files they want to used through --lib
// and they will not get an error from not having unrelated library files
let getGlobalTemplateStringsArrayType: () => ObjectType;

let getGlobalESSymbolType: () => ObjectType;
let getGlobalIterableType: () => GenericType;
let getGlobalIteratorType: () => GenericType;
let getGlobalIterableIteratorType: () => GenericType;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly is the reason these are lazy again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we don't want to give an error even when you don't use any of these feature. For example, if you code only use es6-array features and you specify --lib es2015.array you should not get an error of "can't find 'Symbol' or 'Iterator'": Being lazy allows us to do that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds great! Can you leave that comment above these declarations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep 🍰


let getGlobalClassDecoratorType: () => ObjectType;
let getGlobalParameterDecoratorType: () => ObjectType;
let getGlobalPropertyDecoratorType: () => ObjectType;
Expand Down Expand Up @@ -3973,7 +3978,7 @@ namespace ts {
type = globalBooleanType;
}
else if (type.flags & TypeFlags.ESSymbol) {
type = globalESSymbolType;
type = getGlobalESSymbolType();
}
return type;
}
Expand Down Expand Up @@ -4744,10 +4749,6 @@ namespace ts {
return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
}

function getGlobalESSymbolConstructorSymbol() {
return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"));
}

/**
* Creates a TypeReference for a generic `TypedPropertyDescriptor<T>`.
*/
Expand All @@ -4766,11 +4767,11 @@ namespace ts {
}

function createIterableType(elementType: Type): Type {
return createTypeFromGenericGlobalType(globalIterableType, [elementType]);
return createTypeFromGenericGlobalType(getGlobalIterableType(), [elementType]);
}

function createIterableIteratorType(elementType: Type): Type {
return createTypeFromGenericGlobalType(globalIterableIteratorType, [elementType]);
return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(), [elementType]);
}

function createArrayType(elementType: Type): Type {
Expand Down Expand Up @@ -10415,7 +10416,7 @@ namespace ts {
return getEffectiveDecoratorArgumentType(<Decorator>node, argIndex);
}
else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) {
return globalTemplateStringsArrayType;
return getGlobalTemplateStringsArrayType();
}

// This is not a synthetic argument, so we return 'undefined'
Expand Down Expand Up @@ -14179,7 +14180,7 @@ namespace ts {
if (!typeAsIterable.iterableElementType) {
// As an optimization, if the type is instantiated directly using the globalIterableType (Iterable<number>),
// then just grab its type argument.
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === globalIterableType) {
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === getGlobalIterableType()) {
typeAsIterable.iterableElementType = (<GenericType>type).typeArguments[0];
}
else {
Expand Down Expand Up @@ -14225,7 +14226,7 @@ namespace ts {
if (!typeAsIterator.iteratorElementType) {
// As an optimization, if the type is instantiated directly using the globalIteratorType (Iterator<number>),
// then just grab its type argument.
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === globalIteratorType) {
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === getGlobalIteratorType()) {
typeAsIterator.iteratorElementType = (<GenericType>type).typeArguments[0];
}
else {
Expand Down Expand Up @@ -14269,7 +14270,7 @@ namespace ts {

// As an optimization, if the type is instantiated directly using the globalIterableIteratorType (IterableIterator<number>),
// then just grab its type argument.
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === globalIterableIteratorType) {
if ((type.flags & TypeFlags.Reference) && (<GenericType>type).target === getGlobalIterableIteratorType()) {
return (<GenericType>type).typeArguments[0];
}

Expand Down Expand Up @@ -16879,12 +16880,14 @@ namespace ts {
globalNumberType = getGlobalType("Number");
globalBooleanType = getGlobalType("Boolean");
globalRegExpType = getGlobalType("RegExp");

jsxElementType = getExportedTypeFromNamespace("JSX", JsxNames.Element);
getGlobalClassDecoratorType = memoize(() => getGlobalType("ClassDecorator"));
getGlobalPropertyDecoratorType = memoize(() => getGlobalType("PropertyDecorator"));
getGlobalMethodDecoratorType = memoize(() => getGlobalType("MethodDecorator"));
getGlobalParameterDecoratorType = memoize(() => getGlobalType("ParameterDecorator"));
getGlobalTypedPropertyDescriptorType = memoize(() => getGlobalType("TypedPropertyDescriptor", /*arity*/ 1));
getGlobalESSymbolConstructorSymbol = memoize(() => getGlobalValueSymbol("Symbol"));
getGlobalPromiseType = memoize(() => getGlobalType("Promise", /*arity*/ 1));
tryGetGlobalPromiseType = memoize(() => getGlobalSymbol("Promise", SymbolFlags.Type, /*diagnostic*/ undefined) && getGlobalPromiseType());
getGlobalPromiseLikeType = memoize(() => getGlobalType("PromiseLike", /*arity*/ 1));
Expand All @@ -16893,27 +16896,19 @@ namespace ts {
getGlobalPromiseConstructorLikeType = memoize(() => getGlobalType("PromiseConstructorLike"));
getGlobalThenableType = memoize(createThenableType);

// If we're in ES6 mode, load the TemplateStringsArray.
// Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios.
getGlobalTemplateStringsArrayType = memoize(() => getGlobalType("TemplateStringsArray"));

if (languageVersion >= ScriptTarget.ES6) {
globalTemplateStringsArrayType = getGlobalType("TemplateStringsArray");
globalESSymbolType = getGlobalType("Symbol");
globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol");
globalIterableType = <GenericType>getGlobalType("Iterable", /*arity*/ 1);
globalIteratorType = <GenericType>getGlobalType("Iterator", /*arity*/ 1);
globalIterableIteratorType = <GenericType>getGlobalType("IterableIterator", /*arity*/ 1);
getGlobalESSymbolType = memoize(() => getGlobalType("Symbol"));
getGlobalIterableType = memoize(() => <GenericType>getGlobalType("Iterable", /*arity*/ 1));
getGlobalIteratorType = memoize(() => <GenericType>getGlobalType("Iterator", /*arity*/ 1));
getGlobalIterableIteratorType = memoize(() => <GenericType>getGlobalType("IterableIterator", /*arity*/ 1));
}
else {
globalTemplateStringsArrayType = unknownType;

// Consider putting Symbol interface in lib.d.ts. On the plus side, putting it in lib.d.ts would make it
// extensible for Polyfilling Symbols. But putting it into lib.d.ts could also break users that have
// a global Symbol already, particularly if it is a class.
globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
globalESSymbolConstructorSymbol = undefined;
globalIterableType = emptyGenericType;
globalIteratorType = emptyGenericType;
globalIterableIteratorType = emptyGenericType;
getGlobalESSymbolType = memoize(() => emptyObjectType);
getGlobalIterableType = memoize(() => emptyGenericType);
getGlobalIteratorType = memoize(() => emptyGenericType);
getGlobalIterableIteratorType = memoize(() => emptyGenericType);
}

anyArrayType = createArrayType(anyType);
Expand Down
92 changes: 66 additions & 26 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ namespace ts {
},
{
name: "pretty",
paramType: Diagnostics.KIND,
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental,
type: "boolean"
},
Expand Down Expand Up @@ -332,6 +331,43 @@ namespace ts {
type: "boolean",
description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output
},
{
name: "lib",
type: "list",
element: {
name: "lib",
type: {
// JavaScript only
"es5": "lib.es5.d.ts",
"es6": "lib.es2015.d.ts",
"es2015": "lib.es2015.d.ts",
"es7": "lib.es2016.d.ts",
"es2016": "lib.es2016.d.ts",
// Host only
"dom": "lib.dom.d.ts",
"webworker": "lib.webworker.d.ts",
"scripthost": "lib.scripthost.d.ts",
// ES2015 Or ESNext By-feature options
"es2015.array": "lib.es2015.array.d.ts",
"es2015.collection": "lib.es2015.collection.d.ts",
"es2015.generator": "lib.es2015.generator.d.ts",
"es2015.function": "lib.es2015.function.d.ts",
"es2015.iterable": "lib.es2015.iterable.d.ts",
"es2015.math": "lib.es2015.math.d.ts",
"es2015.number": "lib.es2015.number.d.ts",
"es2015.object": "lib.es2015.object.d.ts",
"es2015.promise": "lib.es2015.promise.d.ts",
"es2015.proxy": "lib.es2015.proxy.d.ts",
"es2015.reflect": "lib.es2015.reflect.d.ts",
"es2015.regexp": "lib.es2015.regexp.d.ts",
"es2015.string": "lib.es2015.string.d.ts",
"es2015.symbol": "lib.es2015.symbol.d.ts",
"es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts",
"es2016.array.include": "lib.es2016.array.include.d.ts"
},
},
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
},
{
name: "strictNullChecks",
type: "boolean",
Expand Down Expand Up @@ -370,6 +406,7 @@ namespace ts {
}

let optionNameMapCache: OptionNameMap;

/* @internal */
export function getOptionNameMap(): OptionNameMap {
if (optionNameMapCache) {
Expand Down Expand Up @@ -399,6 +436,32 @@ namespace ts {
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
}

/* @internal */
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
const key = (value || "").trim().toLowerCase();
const map = opt.type;
if (hasProperty(map, key)) {
return map[key];
}
else {
errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
}
}

/* @internal */
export function parseListTypeOption(opt: CommandLineOptionOfListType, value: string, errors: Diagnostic[]): (string | number)[] {
const values = (value || "").trim().split(",");
switch (opt.element.type) {
case "number":
return ts.map(values, parseInt);
case "string":
return ts.map(values, v => v || "");
default:
return filter(map(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v, errors)), v => !!v);
}
}

/* @internal */
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
Expand Down Expand Up @@ -453,12 +516,12 @@ namespace ts {
i++;
break;
case "list":
options[opt.name] = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i]);
options[opt.name] = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i], errors);
i++;
break;
// If not a primitive, the possible types are specified in what is effectively a map of options.
default:
options[opt.name] = parseCustomTypeOption(<CommandLineOptionOfCustomType>opt, args[i]);
options[opt.name] = parseCustomTypeOption(<CommandLineOptionOfCustomType>opt, args[i], errors);
i++;
break;
}
Expand All @@ -471,29 +534,6 @@ namespace ts {
else {
fileNames.push(s);
}

function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string) {
const key = (value || "").trim().toLowerCase();
const map = opt.type;
if (hasProperty(map, key)) {
return map[key];
}
else {
errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
}
}

function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (string | number)[] {
const values = (value || "").trim().split(",");
switch (opt.element.type) {
case "number":
return ts.map(values, parseInt);
case "string":
return ts.map(values, v => v || "");
default:
return filter(map(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v)), v => !!v);
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2488,6 +2488,10 @@
"category": "Message",
"code": 6078
},
"Specify library files to be included in the compilation: ": {
"category": "Message",
"code": 6079
},
"Specify JSX code generation: 'preserve' or 'react'": {
"category": "Message",
"code": 6080
Expand Down
Loading