Skip to content

Commit

Permalink
Enable '--strictNullChecks'
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Hanson committed Feb 21, 2018
1 parent 8a52ead commit d386f8f
Show file tree
Hide file tree
Showing 151 changed files with 5,158 additions and 5,047 deletions.
98 changes: 0 additions & 98 deletions scripts/tslint/rules/noUnnecessaryTypeAssertion2Rule.ts

This file was deleted.

176 changes: 89 additions & 87 deletions src/compiler/binder.ts

Large diffs are not rendered by default.

63 changes: 32 additions & 31 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace ts {
/**
* State to store the changed files, affected files and cache semantic diagnostics
*/
// TODO: GH#18217 Properties of this interface are frequently asserted to be defined.
export interface BuilderProgramState extends BuilderState {
/**
* Cache of semantic diagnostics for files with their Path being the key
Expand Down Expand Up @@ -43,7 +44,7 @@ namespace ts {

function hasSameKeys<T, U>(map1: ReadonlyMap<T> | undefined, map2: ReadonlyMap<U> | undefined): boolean {
// Has same size and every key is present in both maps
return map1 as ReadonlyMap<T | U> === map2 || map1 && map2 && map1.size === map2.size && !forEachKey(map1, key => !map2.has(key));
return map1 as ReadonlyMap<T | U> === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !forEachKey(map1, key => !map2.has(key));
}

/**
Expand All @@ -58,45 +59,45 @@ namespace ts {
}
state.changedFilesSet = createMap<true>();
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
const canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
if (useOldState) {
// Verify the sanity of old state
if (!oldState.currentChangedFilePath) {
Debug.assert(!oldState.affectedFiles && (!oldState.currentAffectedFilesSignatures || !oldState.currentAffectedFilesSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
if (!oldState!.currentChangedFilePath) {
Debug.assert(!oldState!.affectedFiles && (!oldState!.currentAffectedFilesSignatures || !oldState!.currentAffectedFilesSignatures!.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
}
if (canCopySemanticDiagnostics) {
Debug.assert(!forEachKey(oldState.changedFilesSet, path => oldState.semanticDiagnosticsPerFile.has(path)), "Semantic diagnostics shouldnt be available for changed files");
Debug.assert(!forEachKey(oldState!.changedFilesSet, path => oldState!.semanticDiagnosticsPerFile!.has(path)), "Semantic diagnostics shouldnt be available for changed files");
}

// Copy old state's changed files set
copyEntries(oldState.changedFilesSet, state.changedFilesSet);
copyEntries(oldState!.changedFilesSet, state.changedFilesSet);
}

// Update changed files and copy semantic diagnostics if we can
const referencedMap = state.referencedMap;
const oldReferencedMap = useOldState && oldState.referencedMap;
const oldReferencedMap = useOldState ? oldState!.referencedMap : undefined;
state.fileInfos.forEach((info, sourceFilePath) => {
let oldInfo: Readonly<BuilderState.FileInfo>;
let newReferences: BuilderState.ReferencedSet;
let oldInfo: Readonly<BuilderState.FileInfo> | undefined;
let newReferences: BuilderState.ReferencedSet | undefined;

// if not using old state, every file is changed
if (!useOldState ||
// File wasnt present in old state
!(oldInfo = oldState.fileInfos.get(sourceFilePath)) ||
!(oldInfo = oldState!.fileInfos.get(sourceFilePath)) ||
// versions dont match
oldInfo.version !== info.version ||
// Referenced files changed
!hasSameKeys(newReferences = referencedMap && referencedMap.get(sourceFilePath), oldReferencedMap && oldReferencedMap.get(sourceFilePath)) ||
// Referenced file was deleted in the new program
newReferences && forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState.fileInfos.has(path))) {
newReferences && forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState!.fileInfos.has(path))) {
// Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
state.changedFilesSet.set(sourceFilePath, true);
}
else if (canCopySemanticDiagnostics) {
// Unchanged file copy diagnostics
const diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
if (diagnostics) {
state.semanticDiagnosticsPerFile.set(sourceFilePath, diagnostics);
state.semanticDiagnosticsPerFile!.set(sourceFilePath, diagnostics);
}
}
});
Expand All @@ -108,7 +109,7 @@ namespace ts {
* Verifies that source file is ok to be used in calls that arent handled by next
*/
function assertSourceFileOkWithoutNextAffectedCall(state: BuilderProgramState, sourceFile: SourceFile | undefined) {
Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.path));
Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex! - 1] !== sourceFile || !state.semanticDiagnosticsPerFile!.has(sourceFile.path));
}

/**
Expand All @@ -122,25 +123,25 @@ namespace ts {
const { affectedFiles } = state;
if (affectedFiles) {
const { seenAffectedFiles, semanticDiagnosticsPerFile } = state;
let { affectedFilesIndex } = state;
let affectedFilesIndex = state.affectedFilesIndex!; // TODO: GH#18217
while (affectedFilesIndex < affectedFiles.length) {
const affectedFile = affectedFiles[affectedFilesIndex];
if (!seenAffectedFiles.has(affectedFile.path)) {
if (!seenAffectedFiles!.has(affectedFile.path)) {
// Set the next affected file as seen and remove the cached semantic diagnostics
state.affectedFilesIndex = affectedFilesIndex;
semanticDiagnosticsPerFile.delete(affectedFile.path);
semanticDiagnosticsPerFile!.delete(affectedFile.path);
return affectedFile;
}
seenAffectedFiles.set(affectedFile.path, true);
seenAffectedFiles!.set(affectedFile.path, true);
affectedFilesIndex++;
}

// Remove the changed file from the change set
state.changedFilesSet.delete(state.currentChangedFilePath);
state.changedFilesSet.delete(state.currentChangedFilePath!);
state.currentChangedFilePath = undefined;
// Commit the changes in file signature
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures);
state.currentAffectedFilesSignatures.clear();
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!);
state.currentAffectedFilesSignatures!.clear();
state.affectedFiles = undefined;
}

Expand All @@ -163,7 +164,7 @@ namespace ts {
state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || createMap();
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures);
state.currentChangedFilePath = nextKey.value as Path;
state.semanticDiagnosticsPerFile.delete(nextKey.value as Path);
state.semanticDiagnosticsPerFile!.delete(nextKey.value as Path);
state.affectedFilesIndex = 0;
state.seenAffectedFiles = state.seenAffectedFiles || createMap<true>();
}
Expand All @@ -178,8 +179,8 @@ namespace ts {
state.changedFilesSet.clear();
}
else {
state.seenAffectedFiles.set((affected as SourceFile).path, true);
state.affectedFilesIndex++;
state.seenAffectedFiles!.set((affected as SourceFile).path, true);
state.affectedFilesIndex!++;
}
}

Expand All @@ -197,15 +198,15 @@ namespace ts {
*/
function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
const path = sourceFile.path;
const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
const cachedDiagnostics = state.semanticDiagnosticsPerFile!.get(path);
// Report the semantic diagnostics from the cache if we already have those diagnostics present
if (cachedDiagnostics) {
return cachedDiagnostics;
}

// Diagnostics werent cached, get them from program, and cache the result
const diagnostics = state.program.getSemanticDiagnostics(sourceFile, cancellationToken);
state.semanticDiagnosticsPerFile.set(path, diagnostics);
state.semanticDiagnosticsPerFile!.set(path, diagnostics);
return diagnostics;
}

Expand Down Expand Up @@ -241,7 +242,7 @@ namespace ts {
// Return same program if underlying program doesnt change
let oldState = oldProgram && oldProgram.getState();
if (oldState && newProgram === oldState.program) {
newProgram = undefined;
newProgram = undefined!; // TODO: GH#18217
oldState = undefined;
return oldProgram;
}
Expand All @@ -257,7 +258,7 @@ namespace ts {
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);

// To ensure that we arent storing any references to old program or new program without state
newProgram = undefined;
newProgram = undefined!; // TODO: GH#18217
oldProgram = undefined;
oldState = undefined;

Expand Down Expand Up @@ -326,8 +327,8 @@ namespace ts {
if (!targetSourceFile) {
// Emit and report any errors we ran into.
let sourceMaps: SourceMapData[] = [];
let emitSkipped: boolean;
let diagnostics: Diagnostic[];
let emitSkipped = false;
let diagnostics: Diagnostic[] | undefined;
let emittedFiles: string[] = [];

let affectedEmitResult: AffectedFileResult<EmitResult>;
Expand Down Expand Up @@ -413,7 +414,7 @@ namespace ts {
}
}

let diagnostics: Diagnostic[];
let diagnostics: Diagnostic[] | undefined;
for (const sourceFile of state.program.getSourceFiles()) {
diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken));
}
Expand Down
Loading

0 comments on commit d386f8f

Please sign in to comment.