Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
Browse files Browse the repository at this point in the history
… feature/eslint
  • Loading branch information
a-tarasyuk committed Aug 10, 2019
2 parents c050e55 + 2a2866c commit 23a3b34
Show file tree
Hide file tree
Showing 170 changed files with 1,615 additions and 752 deletions.
3 changes: 2 additions & 1 deletion src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,8 @@ namespace ts {
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord &&
!isIdentifierName(node) &&
!(node.flags & NodeFlags.Ambient)) {
!(node.flags & NodeFlags.Ambient) &&
!(node.flags & NodeFlags.JSDoc)) {

// Report error only if there are no parse errors in file
if (!file.parseDiagnostics.length) {
Expand Down
76 changes: 42 additions & 34 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5937,7 +5937,9 @@ namespace ts {
// Otherwise, fall back to 'any'.
else {
if (setter) {
errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
if (!isPrivateWithinAmbient(setter)) {
errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
}
}
else {
Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
Expand Down Expand Up @@ -26273,8 +26275,9 @@ namespace ts {

let duplicateFunctionDeclaration = false;
let multipleConstructorImplementation = false;
let hasNonAmbientClass = false;
for (const current of declarations) {
const node = <SignatureDeclaration>current;
const node = <SignatureDeclaration | ClassDeclaration | ClassExpression>current;
const inAmbientContext = node.flags & NodeFlags.Ambient;
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
if (inAmbientContextOrInterface) {
Expand All @@ -26288,6 +26291,10 @@ namespace ts {
previousDeclaration = undefined;
}

if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) {
hasNonAmbientClass = true;
}

if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
someNodeFlags |= currentNodeFlags;
Expand Down Expand Up @@ -26336,6 +26343,16 @@ namespace ts {
});
}

if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
// A non-ambient class cannot be an implementation for a non-constructor function/class merge
// TODO: The below just replicates our older error from when classes and functions were
// entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
// might be warranted. :shrug:
forEach(declarations, declaration => {
addDuplicateDeclarationError(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), filter(declarations, d => d !== declaration));
});
}

// Abstract methods can't have an implementation -- in particular, they don't need one.
if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
!hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
Expand Down Expand Up @@ -31649,7 +31666,7 @@ namespace ts {
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
return false;
}
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isPropertyAccessExpression(p.valueDeclaration));
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration));
}

function getPropertiesOfContainerFunction(node: Declaration): Symbol[] {
Expand Down Expand Up @@ -33043,43 +33060,39 @@ namespace ts {
}

function checkGrammarAccessor(accessor: AccessorDeclaration): boolean {
const kind = accessor.kind;
if (languageVersion < ScriptTarget.ES5) {
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
}
else if (accessor.flags & NodeFlags.Ambient) {
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
}
else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
if (!(accessor.flags & NodeFlags.Ambient)) {
if (languageVersion < ScriptTarget.ES5) {
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
}
if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
}
}
else if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) {
if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) {
return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
}
else if (accessor.typeParameters) {
if (accessor.typeParameters) {
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
}
else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
if (!doesAccessorHaveCorrectParameterCount(accessor)) {
return grammarErrorOnNode(accessor.name,
kind === SyntaxKind.GetAccessor ?
accessor.kind === SyntaxKind.GetAccessor ?
Diagnostics.A_get_accessor_cannot_have_parameters :
Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
}
else if (kind === SyntaxKind.SetAccessor) {
if (accessor.kind === SyntaxKind.SetAccessor) {
if (accessor.type) {
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
}
else {
const parameter = accessor.parameters[0];
if (parameter.dotDotDotToken) {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
}
else if (parameter.questionToken) {
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
}
else if (parameter.initializer) {
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
}
const parameter = Debug.assertDefined(getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion.");
if (parameter.dotDotDotToken) {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
}
if (parameter.questionToken) {
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
}
if (parameter.initializer) {
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
}
}
return false;
Expand Down Expand Up @@ -33567,14 +33580,9 @@ namespace ts {

function checkGrammarStatementInAmbientContext(node: Node): boolean {
if (node.flags & NodeFlags.Ambient) {
// An accessors is already reported about the ambient context
if (isAccessor(node.parent)) {
return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
}

// Find containing block which is either Block, ModuleBlock, SourceFile
const links = getNodeLinks(node);
if (!links.hasReportedStatementInAmbientContext && isFunctionLike(node.parent)) {
if (!links.hasReportedStatementInAmbientContext && (isFunctionLike(node.parent) || isAccessor(node.parent))) {
return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
}

Expand Down
4 changes: 0 additions & 4 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,6 @@
"category": "Error",
"code": 1085
},
"An accessor cannot be declared in an ambient context.": {
"category": "Error",
"code": 1086
},
"'{0}' modifier cannot appear on a constructor declaration.": {
"category": "Error",
"code": 1089
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ namespace ts {
for (let i = 0; i < numNodes; i++) {
const currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile!;
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined);
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && hasRecordedExternalHelpers(sourceFile));
const shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit;
const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
if (helpers) {
Expand Down
76 changes: 71 additions & 5 deletions src/compiler/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3629,12 +3629,16 @@ namespace ts {

// Helpers

export function getHelperName(name: string) {
/**
* Gets an identifier for the name of an *unscoped* emit helper.
*/
export function getUnscopedHelperName(name: string) {
return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode);
}

export const valuesHelper: UnscopedEmitHelper = {
name: "typescript:values",
importName: "__values",
scoped: false,
text: `
var __values = (this && this.__values) || function(o) {
Expand All @@ -3654,7 +3658,7 @@ namespace ts {
context.requestEmitHelper(valuesHelper);
return setTextRange(
createCall(
getHelperName("__values"),
getUnscopedHelperName("__values"),
/*typeArguments*/ undefined,
[expression]
),
Expand All @@ -3664,6 +3668,7 @@ namespace ts {

export const readHelper: UnscopedEmitHelper = {
name: "typescript:read",
importName: "__read",
scoped: false,
text: `
var __read = (this && this.__read) || function (o, n) {
Expand All @@ -3688,7 +3693,7 @@ namespace ts {
context.requestEmitHelper(readHelper);
return setTextRange(
createCall(
getHelperName("__read"),
getUnscopedHelperName("__read"),
/*typeArguments*/ undefined,
count !== undefined
? [iteratorRecord, createLiteral(count)]
Expand All @@ -3700,6 +3705,7 @@ namespace ts {

export const spreadHelper: UnscopedEmitHelper = {
name: "typescript:spread",
importName: "__spread",
scoped: false,
text: `
var __spread = (this && this.__spread) || function () {
Expand All @@ -3713,7 +3719,7 @@ namespace ts {
context.requestEmitHelper(spreadHelper);
return setTextRange(
createCall(
getHelperName("__spread"),
getUnscopedHelperName("__spread"),
/*typeArguments*/ undefined,
argumentList
),
Expand All @@ -3723,6 +3729,7 @@ namespace ts {

export const spreadArraysHelper: UnscopedEmitHelper = {
name: "typescript:spreadArrays",
importName: "__spreadArrays",
scoped: false,
text: `
var __spreadArrays = (this && this.__spreadArrays) || function () {
Expand All @@ -3738,7 +3745,7 @@ namespace ts {
context.requestEmitHelper(spreadArraysHelper);
return setTextRange(
createCall(
getHelperName("__spreadArrays"),
getUnscopedHelperName("__spreadArrays"),
/*typeArguments*/ undefined,
argumentList
),
Expand Down Expand Up @@ -4862,6 +4869,65 @@ namespace ts {
return emitNode && emitNode.externalHelpersModuleName;
}

export function hasRecordedExternalHelpers(sourceFile: SourceFile) {
const parseNode = getOriginalNode(sourceFile, isSourceFile);
const emitNode = parseNode && parseNode.emitNode;
return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
}

export function createExternalHelpersImportDeclarationIfNeeded(sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
let namedBindings: NamedImportBindings | undefined;
const moduleKind = getEmitModuleKind(compilerOptions);
if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) {
// use named imports
const helpers = getEmitHelpers(sourceFile);
if (helpers) {
const helperNames: string[] = [];
for (const helper of helpers) {
if (!helper.scoped) {
const importName = (helper as UnscopedEmitHelper).importName;
if (importName) {
pushIfUnique(helperNames, importName);
}
}
}
if (some(helperNames)) {
helperNames.sort(compareStringsCaseSensitive);
// Alias the imports if the names are used somewhere in the file.
// NOTE: We don't need to care about global import collisions as this is a module.
namedBindings = createNamedImports(
map(helperNames, name => isFileLevelUniqueName(sourceFile, name)
? createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name))
: createImportSpecifier(createIdentifier(name), getUnscopedHelperName(name))
)
);
const parseNode = getOriginalNode(sourceFile, isSourceFile);
const emitNode = getOrCreateEmitNode(parseNode);
emitNode.externalHelpers = true;
}
}
}
else {
// use a namespace import
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
if (externalHelpersModuleName) {
namedBindings = createNamespaceImport(externalHelpersModuleName);
}
}
if (namedBindings) {
const externalHelpersImportDeclaration = createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, namedBindings),
createLiteral(externalHelpersModuleNameText)
);
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
return externalHelpersImportDeclaration;
}
}
}

export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
const externalHelpersModuleName = getExternalHelpersModuleName(node);
Expand Down
Loading

0 comments on commit 23a3b34

Please sign in to comment.