/** * Collapses all selected directory nodes. If the selection is a single file or a single collapsed * directory, the selection is set to the directory's parent. */ _collapseSelection(deep: boolean = false): void { const selectedNodes = this._store.getSelectedNodes(); const firstSelectedNode = nullthrows(selectedNodes.first()); if ( selectedNodes.size === 1 && !firstSelectedNode.isRoot && !(firstSelectedNode.isContainer && firstSelectedNode.isExpanded) ) { /* * Select the parent of the selection if the following criteria are met: * * Only 1 node is selected * * The node is not a root * * The node is not an expanded directory */ const parent = nullthrows(firstSelectedNode.parent); this._selectAndTrackNode(parent); } else { selectedNodes.forEach(node => { // Only directories can be expanded. Skip non-directory nodes. if (!node.isContainer) { return; } if (deep) { this._actions.collapseNodeDeep(node.rootUri, node.uri); } else { this._actions.collapseNode(node.rootUri, node.uri); } }); } }
(textBlock, ii) => { // Make absolutely certain that our text is acceptable. textBlock = sanitizeDraftText(textBlock); var end = start + textBlock.length; var inlines = nullthrows(chunk).inlines.slice(start, end); var entities = nullthrows(chunk).entities.slice(start, end); var characterList = List( inlines.map((style, ii) => { var data = {style, entity: (null: ?string)}; if (entities[ii]) { data.entity = entities[ii]; } return CharacterMetadata.create(data); }) ); start = end + 1; return new ContentBlock({ key: generateBlockKey(), type: nullthrows(chunk).blocks[ii].type, depth: nullthrows(chunk).blocks[ii].depth, text: textBlock, characterList, }); }
it('updates the tracked repos states with the new pane item state', () => { const updatePaneItemAction: UpdatePaneItemStateAction = { payload: { repositoryPathToEditors: new Map([ [REPO_PATH_1, [fakeEditor1, fakeEditor2]], [OTHER_REPO_PARH, [fakeEditor3]], ]), }, type: ActionType.UPDATE_PANE_ITEM_STATE, }; const newState = accumulateState(oneRepoState, updatePaneItemAction); const oldShortHeadsToFileList = nullthrows( oneRepoState.repositoryPathToState.get(REPO_PATH_1), ).shortHeadsToFileList; expect(oldShortHeadsToFileList.size).toBe(2); expect(oldShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ 'c.txt', 'd.txt', ]); // Doesn't add untracked repos. expect(newState.repositoryPathToState.size).toBe(1); const newShortHeadsToFileList = nullthrows( newState.repositoryPathToState.get(REPO_PATH_1), ).shortHeadsToFileList; expect(newShortHeadsToFileList.size).toBe(2); expect(newShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ 'file1.txt', 'file2.txt', ]); expect(newShortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual(['e.txt']); });
/** * Get a SelectionState for the supplied mouse event. */ function getSelectionForEvent( event: Object, editorState: EditorState, ): ?SelectionState { let node: ?Node = null; let offset: ?number = null; /* $FlowFixMe(>=0.68.0 site=www,mobile) This comment suppresses an error * found when Flow v0.68 was deployed. To see the error delete this comment * and run Flow. */ if (typeof document.caretRangeFromPoint === 'function') { const dropRange = document.caretRangeFromPoint(event.x, event.y); node = dropRange.startContainer; offset = dropRange.startOffset; } else if (event.rangeParent) { node = event.rangeParent; offset = event.rangeOffset; } else { return null; } node = nullthrows(node); offset = nullthrows(offset); const offsetKey = nullthrows(findAncestorOffsetKey(node)); return getUpdatedSelectionState( editorState, offsetKey, offset, offsetKey, offset, ); }
/** * Get a SelectionState for the supplied mouse event. */ function getSelectionForEvent( event: Object, editorState: EditorState, ): ?SelectionState { let node: ?Node = null; let offset: ?number = null; if (typeof document.caretRangeFromPoint === 'function') { var dropRange = document.caretRangeFromPoint(event.x, event.y); node = dropRange.startContainer; offset = dropRange.startOffset; } else if (event.rangeParent) { node = event.rangeParent; offset = event.rangeOffset; } else { return null; } node = nullthrows(node); offset = nullthrows(offset); const offsetKey = nullthrows(findAncestorOffsetKey(node)); return getUpdatedSelectionState( editorState, offsetKey, offset, offsetKey, offset, ); }
componentDidMount(): void { // Hitting enter when this panel has focus should confirm the dialog. this._disposables.add( atom.commands.add(nullthrows(this._root), 'core:confirm', event => this.props.onConfirm(), ), ); // Hitting escape should cancel the dialog. this._disposables.add( atom.commands.add('atom-workspace', 'core:cancel', event => this.props.onCancel(), ), ); nullthrows(this._password).focus(); const raiseNativeNotification = getNotificationService(); if (raiseNativeNotification != null) { const pendingNotification = raiseNativeNotification( 'Nuclide Remote Connection', 'Nuclide requires additional action to authenticate your remote connection', 2000, false, ); if (pendingNotification != null) { this._disposables.add(pendingNotification); } } }
it('removes old cached short head data when its bookmarks are gone', () => { const updateBookmarksAction: UpdateRepositoryBookmarksAction = { payload: { repository: fakeRepository, bookmarkNames: new Set([SHOTHEAD_1_2]), activeShortHead: SHOTHEAD_1_2, }, type: ActionType.UPDATE_REPOSITORY_BOOKMARKS, }; const oldRpositoryState = oneRepoState.repositoryPathToState.get( REPO_PATH_1, ); expect(nullthrows(oldRpositoryState).shortHeadsToFileList.size).toBe(2); expect( nullthrows(oldRpositoryState).shortHeadsToFileList.has(SHOTHEAD_1_1), ).toBeTruthy(); const newState = accumulateState(oneRepoState, updateBookmarksAction); expect(newState.repositoryPathToState.size).toBe(1); const newRepositoryState: BookShelfRepositoryState = nullthrows( newState.repositoryPathToState.get(REPO_PATH_1), ); expect(newRepositoryState.activeShortHead).toBe(SHOTHEAD_1_2); expect(newRepositoryState.isRestoring).toBe(false); expect(newRepositoryState.shortHeadsToFileList.size).toBe(1); expect( newRepositoryState.shortHeadsToFileList.has(SHOTHEAD_1_1), ).toBeFalsy(); expect(newRepositoryState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual( nullthrows(oldRpositoryState).shortHeadsToFileList.get(SHOTHEAD_1_2), ); });
it('dserializes two repository states', () => { const serializedState: SerializedBookShelfState = ({ repositoryPathToState: [ [ REPO_PATH_1, { ...REPO_STATE_1, shortHeadsToFileList: Array.from( REPO_STATE_1.shortHeadsToFileList.entries(), ), }, ], [ REPO_PATH_2, { ...REPO_STATE_2, shortHeadsToFileList: Array.from( REPO_STATE_2.shortHeadsToFileList.entries(), ), }, ], ], }: any); const deserialized = deserializeBookShelfState(serializedState); expect(deserialized.repositoryPathToState.size).toBe(2); const deserializedRepoState1 = nullthrows( deserialized.repositoryPathToState.get(REPO_PATH_1), ); expect(deserializedRepoState1).not.toBeNull(); invariant(deserializedRepoState1 != null); expect(deserializedRepoState1.activeShortHead).toBe(ACTIVE_SHOTHEAD_1); expect(deserializedRepoState1.isRestoring).toBe(false); expect(deserializedRepoState1.shortHeadsToFileList.size).toBe(1); expect( nullthrows( deserializedRepoState1.shortHeadsToFileList.get(SHOTHEAD_1_1), ).join(','), ).toBe(['a.txt', 'b.txt'].join(',')); const deserializedRepoState2 = nullthrows( deserialized.repositoryPathToState.get(REPO_PATH_2), ); expect(deserializedRepoState2).not.toBeNull(); invariant(deserializedRepoState2 != null); expect(deserializedRepoState2.activeShortHead).toBe(ACTIVE_SHOTHEAD_2); expect(deserializedRepoState2.isRestoring).toBe(false); expect(deserializedRepoState2.shortHeadsToFileList.size).toBe(2); expect( nullthrows( deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_1), ).join(','), ).toBe(['c.txt', 'd.txt'].join(',')); expect( nullthrows( deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_2), ).join(','), ).toBe('e.txt'); });
features.sort((a, b) => { const aIsRepoProvider = packageIsRepositoryProvider(a.pkg); const bIsRepoProvider = packageIsRepositoryProvider(b.pkg); if (aIsRepoProvider !== bIsRepoProvider) { return aIsRepoProvider ? -1 : 1; } const aIndex = nullthrows(originalOrder.get(a)); const bIndex = nullthrows(originalOrder.get(b)); return aIndex - bIndex; });
toString(): string { const func = this._func; if (func != null) { if (this._path == null || this._line == null) { return `${func}()`; } return `${func}() [${this._path}:${this._line}]`; } return `${nullthrows(this._path)}:${nullthrows(this._line)}`; }
// extension must be a string starting with a '.' like '.js' or '.py' function getActiveScriptPath(extension: string): string { const center = atom.workspace.getCenter ? atom.workspace.getCenter() : atom.workspace; const activeEditor: ?atom$TextEditor = center.getActiveTextEditor(); if ( activeEditor == null || !activeEditor.getPath() || !nullthrows(activeEditor.getPath()).endsWith(extension) ) { return ''; } return nuclideUri.getPath(nullthrows(activeEditor.getPath())); }
describe('getShortHeadChangesFromStateStream', () => { const states = new Subject(); const shortHeadChangesStream = getShortHeadChangesFromStateStream(states); const shortHeadChanges: Array<RepositoryShortHeadChange> = []; shortHeadChangesStream.subscribe(change => shortHeadChanges.push(change)); states.next(getDummyBookShelfState()); const newActiveShortHead = 'foo_bar'; const newStateWithShortHeadChange = getDummyBookShelfState(); const newRepositoryState = newStateWithShortHeadChange.repositoryPathToState.get( DUMMY_REPO_PATH_1, ); nullthrows(newRepositoryState).activeShortHead = newActiveShortHead; states.next(newStateWithShortHeadChange); states.complete(); waitsFor(() => shortHeadChanges.length === 1); runs(() => { const {repositoryPath, activeShortHead} = shortHeadChanges[0]; expect(repositoryPath).toBe(DUMMY_REPO_PATH_1); expect(activeShortHead).toBe(newActiveShortHead); }); });
_handleTabChange = (selectedTabName: string) => { if (typeof this.props.onActiveTabChange === 'function') { this.props.onActiveTabChange( nullthrows(this.props.tabs.find(tab => tab.name === selectedTabName)), ); } };
cut: function(editorState: EditorState): EditorState { var content = editorState.getCurrentContent(); var selection = editorState.getSelection(); var targetRange: ?SelectionState = null; if (selection.isCollapsed()) { var anchorKey = selection.getAnchorKey(); var blockEnd = content.getBlockForKey(anchorKey).getLength(); if (blockEnd === selection.getAnchorOffset()) { return editorState; } targetRange = selection.set('focusOffset', blockEnd); } else { targetRange = selection; } targetRange = nullthrows(targetRange); clipboard = getContentStateFragment(content, targetRange); var afterRemoval = DraftModifier.removeRange( content, targetRange, 'forward', ); if (afterRemoval === content) { return editorState; } return EditorState.push(editorState, afterRemoval, 'remove-range'); },
onChange={isChecked => { this.props.projectStore.setStickyCommand( nullthrows(this._debugTarget).getText(), isChecked, ); this.setState({stickyScript: isChecked}); }}
componentWillReceiveProps(nextProps: HunkProps): void { const {hunk, grammar} = nextProps; const changes = hunk.changes; const prevHunk = this.props.hunk; const editor = nullthrows(this.editor); const newText = changes.map(change => change.content.slice(1)).join('\n'); const oldText = prevHunk.changes .map(change => change.content.slice(1)) .join('\n'); const oldGrammar = this.props.grammar; if (newText === oldText && grammar === oldGrammar) { return; } if (newText !== oldText) { editor.setText(newText); } if (grammar !== oldGrammar) { editor.setGrammar(grammar); } this._disposables.dispose(); this._disposables = new UniversalDisposable(); this._createLineMarkers(editor); this._createLineNumbers(editor); }
query.getChildren().forEach(child => { const field = child; if (!(field instanceof RelayQuery.Field) || !field.canHaveSubselections()) { // Only care about linked fields return; } // Get the concrete field from the RelayQueryField const concreteField = nullthrows( QueryBuilder.getField(field.getConcreteQueryNode()), ); // Build the identifying argument for the query let identifyingArgName; let identifyingArgType; const identifyingArg = concreteField.calls && concreteField.calls[0]; if (identifyingArg) { identifyingArgName = identifyingArg.name; identifyingArgType = identifyingArg.metadata && identifyingArg.metadata.type; } // Build the concrete query const concreteQuery = { calls: concreteField.calls, children: concreteField.children, directives: [], // @include/@skip directives are processed within getChildren() fieldName: concreteField.fieldName, isDeferred: false, kind: 'Query', metadata: { identifyingArgName, identifyingArgType, isAbstract: concreteField.metadata && concreteField.metadata.isAbstract, isPlural: concreteField.metadata && concreteField.metadata.isPlural, }, name: query.getName(), // Note that classic queries are typed as the type of the root field, not // the `Query` type type: field.getType(), }; // Construct a root query const root = RelayQuery.Root.create( concreteQuery, RelayMetaRoute.get('$RelayEnvironment'), query.getVariables(), ); // Construct the payload that would have been returned had `root` been // used to fetch data. const serializationKey = field.getSerializationKey(); const rootPayload = {}; if (!response.hasOwnProperty(serializationKey)) { // Data is missing for this field. This can occur when the field is empty // due to a failing conditional (@include/@skip) in its subtree. return; } rootPayload[root.getFieldName()] = response[serializationKey]; results.push({ field, root, rootPayload, }); });
pack => { if (featureNames.has(pack.name)) { onWillInitializePackageDisposable.dispose(); const rootPackage = atom.packages.getLoadedPackage(this._pkgName); nullthrows(rootPackage).initializeIfNeeded(); } },
componentDidMount() { this._subscriptions = new UniversalDisposable( atom.commands.add(nullthrows(this._scrollerNode), 'atom-ide:filter', () => this.focusSearch(), ), ); }
getFatQuery(): RelayQuery.Fragment { if (!this._fatQuery) { const fragment = fromGraphQL.Fragment(this.mutation.getFatQuery()); invariant( fragment instanceof RelayQuery.Fragment, 'RelayMutationQueue: Expected `getFatQuery` to return a GraphQL ' + 'Fragment' ); this._fatQuery = nullthrows(flattenRelayQuery( fragment, { // TODO #10341736 // This used to be `preserveEmptyNodes: fragment.isPattern()`. We // discovered that products were not marking their fat queries as // patterns (by adding `@relay(pattern: true)`) which was causing // `preserveEmptyNodes` to be false. This meant that empty fields, // would be stripped instead of being used to produce an intersection // with the tracked query. Products were able to do this because the // Babel Relay plugin doesn't produce validation errors for empty // fields. It should, and we will make it do so, but for now we're // going to set this to `true` always, and make the plugin warn when // it encounters an empty field that supports subselections in a // non-pattern fragment. Revert this when done. preserveEmptyNodes: true, shouldRemoveFragments: true, } )); } return this._fatQuery; }
.map((filePath, index) => { return { filePath, displayPath: displayPaths[index], fileStatus: nullthrows(fileStatuses.get(filePath)), }; })
_onScroll = (e: Object) => { const newScrollY = e.nativeEvent.contentOffset.y; this._isScrolling = this._scrollOffsetY !== newScrollY; this._scrollOffsetY = newScrollY; this._frameHeight = e.nativeEvent.layoutMeasurement.height; // We don't want to enqueue any updates if any cells are in the middle of an incremental render, // because it would just be wasted work. if (this._cellsInProgress.size === 0) { this._enqueueComputeRowsToRender(); } if (this.props.onViewableRowsChanged && Object.keys(this._rowFrames).length) { const viewableRows = ViewabilityHelper.computeViewableRows( this.props.viewablePercentThreshold, this._rowFrames, this.props.data, e.nativeEvent.contentOffset.y, e.nativeEvent.layoutMeasurement.height ); if (deepDiffer(viewableRows, this._viewableRows)) { this._viewableRows = viewableRows; nullthrows(this.props.onViewableRowsChanged)(this._viewableRows); } } this.props.onScroll && this.props.onScroll(e); };
).flatMap(textEditor => { const buffer = textEditor.getBuffer(); if (buffers.has(buffer)) { return Observable.empty(); } buffers.add(buffer); const bufferPath = nullthrows(buffer.getPath()); const bufferReloads = observableFromSubscribeFunction( buffer.onDidReload.bind(buffer), ); const bufferChanges = observableFromSubscribeFunction( buffer.onDidChangeText.bind(buffer), ); // TODO (tjfryan): handle renames `onDidChangePath` // This is in a flatMap, so we need to make sure this terminates // We can terminate, `takeUntil`, buffer is destroyed // And make sure to clear the cached diff for the buffer once we no // longer care about it const bufferDestroyed = observableFromSubscribeFunction( buffer.onDidDestroy.bind(buffer), ).do(() => { buffers.delete(buffer); repository.deleteDiffInfo(bufferPath); fileContentsAtHead.delete(bufferPath); }); // recalculate on bufferReload, bufferChanges, and when we get // this file's data from hg cat return Observable.merge( bufferReloads, bufferChanges, fetchFileContentsAtHead.filter(fileContentsList => fileContentsList.some( fileInfo => nuclideUri.join( repository.getWorkingDirectory(), fileInfo.abspath, ) === bufferPath, ), ), ) .let(fastDebounce(200)) .switchMap(() => { const oldContents = fileContentsAtHead.get(bufferPath); if (oldContents == null) { return Observable.empty(); } const newContents = buffer.getText(); return gitDiffStrings(oldContents, newContents) .map(diffOutput => parseHgDiffUnifiedOutput(diffOutput)) .do(diffInfo => { repository.setDiffInfo(bufferPath, diffInfo); }); }) .takeUntil(bufferDestroyed); });
.flatMap(() => { const bufferPath = nullthrows(textEditor.getPath()); // TODO (tjfryan): do something to handle generated files if (fileContentsAtHead.has(bufferPath)) { return Observable.empty(); } bufferedFilesToCat.push(repository.relativize(bufferPath)); if (bufferedFilesToCat.length > 1) { return Observable.empty(); } // use nextTick to buffer many files being requested at once // (maybe should use timeout instead?) return Observable.fromPromise(nextTick()).switchMap(() => { const filesToCat = [...bufferedFilesToCat]; bufferedFilesToCat.length = 0; return repository .fetchMultipleFilesContentAtRevision( filesToCat, hgConstants.HEAD_REVISION_EXPRESSION, ) .catch(() => // hg uses errorCode 1 as "nothing went wrong but nothing was found" Observable.empty(), ); }); });
it("keeps the existing state when it's there", () => { expect(oneRepoState.repositoryPathToState.size).toBe(1); const addRepositoryAction: AddProjectRepositoryAction = { payload: { repository: fakeRepository, }, type: ActionType.ADD_PROJECT_REPOSITORY, }; const newState = accumulateState(oneRepoState, addRepositoryAction); expect(fakeRepository.getWorkingDirectory).toHaveBeenCalled(); expect(newState.repositoryPathToState.size).toBe(1); const keptRepoState: BookShelfRepositoryState = nullthrows( newState.repositoryPathToState.get(REPO_PATH_1), ); expect(keptRepoState).toBeDefined(); expect(keptRepoState.activeShortHead).toBe(ACTIVE_SHOTHEAD_1); expect(keptRepoState.isRestoring).toBeFalsy(); expect(keptRepoState.shortHeadsToFileList.size).toBe(2); expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ 'c.txt', 'd.txt', ]); expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual([ 'e.txt', ]); });
_onChange = (event: CheckBoxEvent) => { const value = this.props.value ?? false; nullthrows(this._nativeRef).setNativeProps({value: value}); // Change the props after the native props are set in case the props // change removes the component this.props.onChange && this.props.onChange(event); this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value); };
function printDirectivesAndChildren(node, printerState: PrinterState): string { const conditionDirectives = printDirectives(node, isConditionDirective); const otherDirectives = printDirectives(node, isNonConditionDirective); return ( otherDirectives + (conditionDirectives ? ' {' + newLine + oneIndent + '...' + conditionDirectives + nullthrows(printChildren(node, printerState, oneIndent)) + newLine + '}' : nullthrows(printChildren(node, printerState, ''))) ); }
getTextContentFromFiles(files, fileText => { fileText && editor.update( insertTextAtSelection( editorState, nullthrows(dropSelection), // flow wtf fileText, ), ); });
onResponderTerminationRequest: (): boolean => { const {onResponderTerminationRequest} = this.props; if (!nullthrows(this.touchableHandleResponderTerminationRequest)()) { return false; } if (onResponderTerminationRequest == null) { return true; } return onResponderTerminationRequest(); },
return postOrder(process.pid, mapChildren(viewPs), (pid, children) => { const process = nullthrows(viewPs.get(pid)); return { pid, command: process.command, cpuPercentage: process.pcpu, children, ioBytesStats: ioMap.get(pid), }; });