Skip to content

Commit

Permalink
Merge branch 'master' into deprecated_support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingwl committed Jun 18, 2020
2 parents 2d189dc + b977f86 commit b8142f9
Show file tree
Hide file tree
Showing 122 changed files with 8,289 additions and 909 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"chalk": "latest",
"convert-source-map": "latest",
"del": "5.1.0",
"diff": "^4.0.2",
"eslint": "6.8.0",
"eslint-formatter-autolinkable-stylish": "1.1.2",
"eslint-plugin-import": "2.20.2",
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace ts {
reportDeprecated?: {}
source?: string;
relatedInformation?: ReusableDiagnosticRelatedInformation[];
skippedOn?: keyof CompilerOptions;
}

export interface ReusableDiagnosticRelatedInformation {
Expand Down Expand Up @@ -270,6 +271,7 @@ namespace ts {
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportsDeprecated = diagnostic.reportDeprecated;
result.source = diagnostic.source;
result.skippedOn = diagnostic.skippedOn;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
Expand Down Expand Up @@ -678,7 +680,7 @@ namespace ts {
const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
// Report the bind and check diagnostics from the cache if we already have those diagnostics present
if (cachedDiagnostics) {
return cachedDiagnostics;
return filterSemanticDiagnotics(cachedDiagnostics, state.compilerOptions);
}
}

Expand All @@ -687,7 +689,7 @@ namespace ts {
if (state.semanticDiagnosticsPerFile) {
state.semanticDiagnosticsPerFile.set(path, diagnostics);
}
return diagnostics;
return filterSemanticDiagnotics(diagnostics, state.compilerOptions);
}

export type ProgramBuildInfoDiagnostic = string | [string, readonly ReusableDiagnostic[]];
Expand Down Expand Up @@ -819,6 +821,7 @@ namespace ts {
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportDeprecated = diagnostic.reportsDeprecated;
result.source = diagnostic.source;
result.skippedOn = diagnostic.skippedOn;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
Expand Down
134 changes: 99 additions & 35 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ namespace ts {
{
name: "noEmit",
type: "boolean",
affectsEmit: true,
showInSimplifiedHelpView: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Do_not_emit_outputs,
Expand Down Expand Up @@ -766,6 +765,12 @@ namespace ts {
category: Diagnostics.Advanced_Options,
description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
},
{
name: "jsxFragmentFactory",
type: "string",
category: Diagnostics.Advanced_Options,
description: Diagnostics.Specify_the_JSX_fragment_factory_function_to_use_when_targeting_react_JSX_emit_with_jsxFactory_compiler_option_is_specified_e_g_Fragment
},
{
name: "resolveJsonModule",
type: "boolean",
Expand Down
16 changes: 14 additions & 2 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4458,6 +4458,10 @@
"category": "Error",
"code": 6309
},
"Referenced project '{0}' may not disable emit.": {
"category": "Error",
"code": 6310
},
"Project '{0}' is out of date because oldest output '{1}' is older than newest input '{2}'": {
"category": "Message",
"code": 6350
Expand Down Expand Up @@ -5032,11 +5036,11 @@
"category": "Error",
"code": 17015
},
"JSX fragment is not supported when using --jsxFactory": {
"The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option.": {
"category": "Error",
"code": 17016
},
"JSX fragment is not supported when using an inline JSX factory pragma": {
"An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments.": {
"category": "Error",
"code": 17017
},
Expand Down Expand Up @@ -5842,5 +5846,13 @@
"Only numeric enums can have computed members, but this expression has type '{0}'. If you do not need exhaustiveness checks, consider using an object literal instead.": {
"category": "Error",
"code": 18033
},
"Specify the JSX fragment factory function to use when targeting 'react' JSX emit with 'jsxFactory' compiler option is specified, e.g. 'Fragment'.": {
"category": "Message",
"code": 18034
},
"Invalid value for 'jsxFragmentFactory'. '{0}' is not a valid identifier or qualified-name.": {
"category": "Error",
"code": 18035
}
}
3 changes: 2 additions & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ namespace ts {
// Write build information if applicable
if (!buildInfoPath || targetSourceFile || emitSkipped) return;
const program = host.getProgramBuildInfo();
if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
if (host.isEmitBlocked(buildInfoPath)) {
emitSkipped = true;
return;
}
Expand Down Expand Up @@ -660,6 +660,7 @@ namespace ts {
getTypeReferenceDirectivesForSymbol: notImplemented,
isLiteralConstDeclaration: notImplemented,
getJsxFactoryEntity: notImplemented,
getJsxFragmentFactoryEntity: notImplemented,
getAllAccessorDeclarations: notImplemented,
getSymbolOfExternalModuleSpecifier: notImplemented,
isBindingCapturedByNode: notImplemented,
Expand Down
22 changes: 13 additions & 9 deletions src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ namespace ts {
);
}

function createJsxFragmentFactoryExpression(factory: NodeFactory, jsxFragmentFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
return jsxFragmentFactoryEntity ?
createJsxFactoryExpressionFromEntityName(factory, jsxFragmentFactoryEntity, parent) :
factory.createPropertyAccessExpression(
createReactNamespace(reactNamespace, parent),
"Fragment"
);
}

export function createExpressionForJsxElement(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, tagName: Expression, props: Expression | undefined, children: readonly Expression[] | undefined, parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
const argumentsList = [tagName];
if (props) {
Expand Down Expand Up @@ -87,14 +96,9 @@ namespace ts {
);
}

export function createExpressionForJsxFragment(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
const tagName = factory.createPropertyAccessExpression(
createReactNamespace(reactNamespace, parentElement),
"Fragment"
);

const argumentsList = [<Expression>tagName];
argumentsList.push(factory.createNull());
export function createExpressionForJsxFragment(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, jsxFragmentFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
const tagName = createJsxFragmentFactoryExpression(factory, jsxFragmentFactoryEntity, reactNamespace, parentElement);
const argumentsList = [tagName, factory.createNull()];

if (children && children.length > 0) {
if (children.length > 1) {
Expand Down Expand Up @@ -820,4 +824,4 @@ namespace ts {
export function isStaticModifier(node: Modifier): node is StaticKeyword {
return node.kind === SyntaxKind.StaticKeyword;
}
}
}
8 changes: 5 additions & 3 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3120,7 +3120,7 @@ namespace ts {
return finishNode(factory.createRestTypeNode(parseType()), pos);
}
const type = parseType();
if (!(contextFlags & NodeFlags.JSDoc) && isJSDocNullableType(type) && type.pos === type.type.pos) {
if (isJSDocNullableType(type) && type.pos === type.type.pos) {
const node = factory.createOptionalTypeNode(type.type);
setTextRange(node, type);
(node as Mutable<Node>).flags = type.flags;
Expand Down Expand Up @@ -3361,7 +3361,7 @@ namespace ts {
break;
case SyntaxKind.QuestionToken:
// If not in JSDoc and next token is start of a type we have a conditional type
if (!(contextFlags & NodeFlags.JSDoc) && lookAhead(nextTokenIsStartOfType)) {
if (lookAhead(nextTokenIsStartOfType)) {
return type;
}
nextToken();
Expand Down Expand Up @@ -8577,7 +8577,9 @@ namespace ts {
});
break;
}
case "jsx": return; // Accessed directly
case "jsx":
case "jsxfrag":
return; // Accessed directly
default: Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future?
}
});
Expand Down
37 changes: 27 additions & 10 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,7 @@ namespace ts {
function getPrependNodes() {
return createPrependNodes(
projectReferences,
(_ref, index) => resolvedProjectReferences![index]!.commandLine,
(_ref, index) => resolvedProjectReferences![index]?.commandLine,
fileName => {
const path = toPath(fileName);
const sourceFile = getSourceFileByPath(path);
Expand Down Expand Up @@ -1719,7 +1719,7 @@ namespace ts {

function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly Diagnostic[] {
return concatenate(
getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken),
filterSemanticDiagnotics(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), options),
getProgramDiagnostics(sourceFile)
);
}
Expand Down Expand Up @@ -3011,10 +3011,6 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
}

if (!options.listFilesOnly && options.noEmit && isIncrementalCompilation(options)) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", options.incremental ? "incremental" : "composite");
}

verifyProjectReferences();

// List of collected files is complete; validate exhautiveness if this is a project with a file list
Expand Down Expand Up @@ -3196,6 +3192,15 @@ namespace ts {
createOptionValueDiagnostic("reactNamespace", Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
}

if (options.jsxFragmentFactory) {
if (!options.jsxFactory) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "jsxFragmentFactory", "jsxFactory");
}
if (!parseIsolatedEntityName(options.jsxFragmentFactory, languageVersion)) {
createOptionValueDiagnostic("jsxFragmentFactory", Diagnostics.Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFragmentFactory);
}
}

// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
if (!options.noEmit && !options.suppressOutputPathCheck) {
const emitHost = getEmitHost();
Expand Down Expand Up @@ -3269,7 +3274,7 @@ namespace ts {
}

function verifyProjectReferences() {
const buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined;
const buildInfoPath = !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined;
forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
const parentFile = parent && parent.sourceFile as JsonSourceFile;
Expand All @@ -3278,11 +3283,12 @@ namespace ts {
return;
}
const options = resolvedRef.commandLine.options;
if (!options.composite) {
if (!options.composite || options.noEmit) {
// ok to not have composite if the current program is container only
const inputs = parent ? parent.commandLine.fileNames : rootNames;
if (inputs.length) {
createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
if (!options.composite) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
if (options.noEmit) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path);
}
}
if (ref.prepend) {
Expand Down Expand Up @@ -3648,7 +3654,13 @@ namespace ts {
cancellationToken: CancellationToken | undefined
): EmitResult | undefined {
const options = program.getCompilerOptions();
if (options.noEmit) return emitSkippedWithNoDiagnostics;
if (options.noEmit) {
// Cache the semantic diagnostics
program.getSemanticDiagnostics(sourceFile, cancellationToken);
return sourceFile || outFile(options) ?
emitSkippedWithNoDiagnostics :
program.emitBuildInfo(writeFile, cancellationToken);
}

// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
Expand All @@ -3675,6 +3687,11 @@ namespace ts {
return { diagnostics, sourceMaps: undefined, emittedFiles, emitSkipped: true };
}

/*@internal*/
export function filterSemanticDiagnotics(diagnostic: readonly Diagnostic[], option: CompilerOptions): readonly Diagnostic[] {
return filter(diagnostic, d => !d.skippedOn || !option[d.skippedOn]);
}

/*@internal*/
interface CompilerHostLike {
useCaseSensitiveFileNames(): boolean;
Expand Down
1 change: 1 addition & 0 deletions src/compiler/transformers/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ namespace ts {
const element = createExpressionForJsxFragment(
factory,
context.getEmitResolver().getJsxFactoryEntity(currentSourceFile),
context.getEmitResolver().getJsxFragmentFactoryEntity(currentSourceFile),
compilerOptions.reactNamespace!, // TODO: GH#18217
mapDefined(children, transformJsxChildToExpression),
node,
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3462,7 +3462,9 @@ namespace ts {
/* @internal */ version: string;
/* @internal */ pragmas: ReadonlyPragmaMap;
/* @internal */ localJsxNamespace?: __String;
/* @internal */ localJsxFragmentNamespace?: __String;
/* @internal */ localJsxFactory?: EntityName;
/* @internal */ localJsxFragmentFactory?: EntityName;

/* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
}
Expand Down Expand Up @@ -4471,6 +4473,7 @@ namespace ts {
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[] | undefined;
isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
getJsxFactoryEntity(location?: Node): EntityName | undefined;
getJsxFragmentFactoryEntity(location?: Node): EntityName | undefined;
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined;
isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean;
Expand Down Expand Up @@ -5533,6 +5536,7 @@ namespace ts {
reportsDeprecated?: {}
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
/* @internal */ skippedOn?: keyof CompilerOptions;
}

export interface DiagnosticRelatedInformation {
Expand Down Expand Up @@ -5692,6 +5696,7 @@ namespace ts {
/* @internal */ pretty?: boolean;
reactNamespace?: string;
jsxFactory?: string;
jsxFragmentFactory?: string;
composite?: boolean;
incremental?: boolean;
tsBuildInfoFile?: string;
Expand Down Expand Up @@ -7941,6 +7946,10 @@ namespace ts {
args: [{ name: "factory" }],
kind: PragmaKindFlags.MultiLine
},
"jsxfrag": {
args: [{ name: "factory" }],
kind: PragmaKindFlags.MultiLine
},
} as const;

/* @internal */
Expand Down
14 changes: 11 additions & 3 deletions src/harness/harnessIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@ namespace Harness {
export interface BaselineOptions {
Subfolder?: string;
Baselinefolder?: string;
PrintDiff?: true;
}

export function localPath(fileName: string, baselineFolder?: string, subfolder?: string) {
Expand Down Expand Up @@ -1347,7 +1348,7 @@ namespace Harness {
return { expected, actual };
}

function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string) {
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, opts?: BaselineOptions) {
// For now this is written using TypeScript, because sys is not available when running old test cases.
// But we need to move to sys once we have
// Creates the directory including its parent if not already present
Expand Down Expand Up @@ -1381,7 +1382,14 @@ namespace Harness {
else {
IO.writeFile(actualFileName, encodedActual);
}
throw new Error(`The baseline file ${relativeFileName} has changed.`);
if (require && opts && opts.PrintDiff) {
const Diff = require("diff");
const patch = Diff.createTwoFilesPatch("Expected", "Actual", expected, actual, "The current baseline", "The new version");
throw new Error(`The baseline file ${relativeFileName} has changed.${ts.ForegroundColorEscapeSequences.Grey}\n\n${patch}`);
}
else {
throw new Error(`The baseline file ${relativeFileName} has changed.`);
}
}
}

Expand All @@ -1391,7 +1399,7 @@ namespace Harness {
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
}
const comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, opts);
}

export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]> | null, opts?: BaselineOptions, referencedExtensions?: string[]): void {
Expand Down
Loading

0 comments on commit b8142f9

Please sign in to comment.