Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ import { ConversationStore, IConversationStore } from '../../conversationStore/n
import { SimilarFilesContextService } from '../../inlineEdits/vscode-node/similarFilesContext';
import { IIntentService, IntentService } from '../../intents/node/intentService';
import { INewWorkspacePreviewContentManager, NewWorkspacePreviewContentManagerImpl } from '../../intents/node/newIntent';
import { ITestGenInfoStorage, TestGenInfoStorage } from '../../intents/node/testIntent/testInfoStorage';
import { LanguageContextProviderService } from '../../languageContextProvider/vscode-node/languageContextProviderService';
import { ILinkifyService, LinkifyService } from '../../linkify/common/linkifyService';
import { DebugCommandToConfigConverter, IDebugCommandToConfigConverter } from '../../onboardDebug/node/commandToConfigConverter';
Expand Down Expand Up @@ -212,7 +211,6 @@ export function registerServices(builder: IInstantiationServiceBuilder, extensio
builder.define(IGithubCodeSearchService, new SyncDescriptor(GithubCodeSearchService));
builder.define(IGithubAvailableEmbeddingTypesService, new SyncDescriptor(GithubAvailableEmbeddingTypesService));

builder.define(ITestGenInfoStorage, new SyncDescriptor(TestGenInfoStorage)); // Used for test generation (/tests intent)
builder.define(IParserService, new SyncDescriptor(ParserServiceImpl, [/*useWorker*/ true]));
builder.define(IIntentService, new SyncDescriptor(IntentService));
builder.define(INaiveChunkingService, new SyncDescriptor(NaiveChunkingService));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { IResponsePart } from '../../../../platform/chat/common/chatMLFetcher';
import { ChatLocation } from '../../../../platform/chat/common/commonTypes';
import { IChatEndpoint } from '../../../../platform/networking/common/networking';
import { IParserService } from '../../../../platform/parser/node/parserService';
import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService';
import { isNotebookCellOrNotebookChatInput } from '../../../../util/common/notebooks';
import { CancellationToken } from '../../../../util/vs/base/common/cancellation';
import { illegalArgument } from '../../../../util/vs/base/common/errors';
Expand All @@ -27,12 +26,9 @@ import { Tag } from '../../../prompts/node/base/tag';
import { ChatToolReferences, ChatVariables, UserQuery } from '../../../prompts/node/panel/chatVariables';
import { HistoryWithInstructions } from '../../../prompts/node/panel/conversationHistory';
import { CustomInstructions } from '../../../prompts/node/panel/customInstructions';
import { CodeBlock } from '../../../prompts/node/panel/safeElements';
import { SelectionSplitKind, SummarizedDocumentData, SummarizedDocumentWithSelection } from './summarizedDocumentWithSelection';
import { TestDeps } from './testDeps';
import { ITestGenInfo, ITestGenInfoStorage } from './testInfoStorage';
import { TestsIntent } from './testIntent';
import { formatRequestAndUserQuery } from './testPromptUtil';
import { PseudoStopStartResponseProcessor } from '../../../prompt/node/pseudoStartStopConversationCallback';


Expand All @@ -50,7 +46,6 @@ export class TestFromTestInvocation implements IIntentInvocation {
private readonly context: IDocumentContext,
private readonly alreadyConsumedChatVariable: vscode.ChatPromptReference | undefined,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ITestGenInfoStorage private readonly testGenInfoStorage: ITestGenInfoStorage,
) {
}

Expand All @@ -61,12 +56,6 @@ export class TestFromTestInvocation implements IIntentInvocation {
>,
token: vscode.CancellationToken
) {
const testGenInfo = this.testGenInfoStorage.sourceFileToTest;

if (testGenInfo !== undefined) {
this.testGenInfoStorage.sourceFileToTest = undefined;
}

const renderer = PromptRenderer.create(
this.instantiationService,
this.endpoint,
Expand All @@ -75,7 +64,6 @@ export class TestFromTestInvocation implements IIntentInvocation {
context: this.context,
promptContext,
alreadyConsumedChatVariable: this.alreadyConsumedChatVariable,
testGenInfo,
}
);

Expand Down Expand Up @@ -114,14 +102,12 @@ type Props = PromptElementProps<{
context: IDocumentContext;
promptContext: IBuildPromptContext;
alreadyConsumedChatVariable: vscode.ChatPromptReference | undefined;
testGenInfo: ITestGenInfo | undefined;
}>;

class TestFromTestPrompt extends PromptElement<Props> {

constructor(
props: Props,
@IWorkspaceService private readonly workspaceService: IWorkspaceService,
@IParserService private readonly parserService: IParserService
) {
super(props);
Expand All @@ -130,32 +116,13 @@ class TestFromTestPrompt extends PromptElement<Props> {
override async render(_state: void, sizing: PromptSizing) {

const { history, query, chatVariables, } = this.props.promptContext;
const { context, testGenInfo, alreadyConsumedChatVariable, } = this.props;
const { context, alreadyConsumedChatVariable, } = this.props;

if (isNotebookCellOrNotebookChatInput(context.document.uri)) {
throw illegalArgument('TestFromTestPrompt should not be used for notebooks');
}

const testedSymbolIdentifier = testGenInfo?.identifier;

const requestAndUserQuery = testGenInfo === undefined
? `Please, generate more tests, taking into account existing tests. ${query}`.trim()
: formatRequestAndUserQuery({
workspaceService: this.workspaceService,
chatVariables,
userQuery: query,
testFileToWriteTo: context.document.uri,
testedSymbolIdentifier,
context,
});

let testedDeclarationExcerpt = undefined;
if (testGenInfo !== undefined) {
const srcFileDoc = await this.workspaceService.openTextDocument(testGenInfo.uri);
const declStart = testGenInfo.target.start;
const expandedRange = testGenInfo.target.with(declStart.with(declStart.line, 0));
testedDeclarationExcerpt = srcFileDoc.getText(expandedRange);
}
const requestAndUserQuery = `Please, generate more tests, taking into account existing tests. ${query}`.trim();

const data = await SummarizedDocumentData.create(
this.parserService,
Expand Down Expand Up @@ -190,21 +157,15 @@ class TestFromTestPrompt extends PromptElement<Props> {
<ChatVariables priority={750} chatVariables={filteredChatVariables} />

{/* include summarized source file: */}
<Test2Impl priority={800} documentContext={context} srcFile={testGenInfo} />
<Test2Impl priority={800} documentContext={context} />
{/* include summarized test file: */}
<Tag name='testsFile' priority={900}>
<SummarizedDocumentWithSelection
documentData={data}
tokenBudget={sizing.tokenBudget / 3}
_allowEmptySelection={true}
/>{ /* FIXME@ulugbekna: rework summarization to be more intelligent */}
{/* repeat tested declaration -- otherwise, model seems to forget it: */}
</Tag>
{testGenInfo !== undefined && testedDeclarationExcerpt !== undefined && /* FIXME@ulugbekna: include class around */
<Tag name='codeToTest' priority={900}>
{`Repeating excerpt from \`${testGenInfo?.uri.path}\` here that needs to be tested:`}{/* FIXME@ulugbekna */}<br />
<CodeBlock uri={testGenInfo.uri} languageId={context.language.languageId} code={testedDeclarationExcerpt} />
</Tag>}
<Tag name='userPrompt' priority={900}>
<UserQuery chatVariables={filteredChatVariables} query={requestAndUserQuery} />
</Tag>
Expand Down

This file was deleted.

25 changes: 5 additions & 20 deletions extensions/copilot/src/extension/prompt/node/test2Impl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@

import { PromptElement, PromptElementProps, PromptSizing } from '@vscode/prompt-tsx';
import assert from 'assert';
import type * as vscode from 'vscode';
import { IIgnoreService } from '../../../platform/ignore/common/ignoreService';
import { IWorkspaceService } from '../../../platform/workspace/common/workspaceService';
import { CancellationToken } from '../../../util/vs/base/common/cancellation';
import { URI } from '../../../util/vs/base/common/uri';
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
import { ITestGenInfo } from '../../intents/node/testIntent/testInfoStorage';
import { Tag } from '../../prompts/node/base/tag';
import { DocumentSummarizer } from '../../prompts/node/inline/summarizedDocument/summarizeDocumentHelpers';
import { CodeBlock } from '../../prompts/node/panel/safeElements';
Expand All @@ -24,10 +21,6 @@ type Props = PromptElementProps<{
* Document here is expected to be a test file.
*/
documentContext: IDocumentContext;
/**
* Src (ie impl) file to include if already known.
*/
srcFile?: ITestGenInfo;
}>;

/**
Expand All @@ -46,21 +39,13 @@ export class Test2Impl extends PromptElement<Props> {

override async render(state: void, sizing: PromptSizing) {

const { documentContext, srcFile, } = this.props;
const { documentContext } = this.props;

assert(isTestFile(documentContext.document), 'Test2Impl must be invoked on a test file.');

let candidateFile: URI | undefined;
let selection: vscode.Range | undefined;

if (srcFile) {
candidateFile = srcFile.uri;
selection = srcFile.target;
} else {
// @ulugbekna: find file that this test file corresponds to
const finder = this.instaService.createInstance(TestFileFinder);
candidateFile = await finder.findFileForTestFile(documentContext.document, CancellationToken.None);
}
// @ulugbekna: find file that this test file corresponds to
const finder = this.instaService.createInstance(TestFileFinder);
const candidateFile = await finder.findFileForTestFile(documentContext.document, CancellationToken.None);

if (candidateFile === undefined || await this.ignoreService.isCopilotIgnored(candidateFile)) {
return undefined;
Expand All @@ -73,7 +58,7 @@ export class Test2Impl extends PromptElement<Props> {
const summarizedDoc = await docSummarizer.summarizeDocument(
doc,
documentContext.fileIndentInfo,
selection,
undefined,
sizing.tokenBudget,
);

Expand Down
2 changes: 0 additions & 2 deletions extensions/copilot/src/extension/test/vscode-node/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ import { ICopilotInlineCompletionItemProviderService, NullCopilotInlineCompletio
import { IPromptWorkspaceLabels, PromptWorkspaceLabels } from '../../context/node/resolvers/promptWorkspaceLabels';
import { IUserFeedbackService, UserFeedbackService } from '../../conversation/vscode-node/userActions';
import { ConversationStore, IConversationStore } from '../../conversationStore/node/conversationStore';
import { ITestGenInfoStorage, TestGenInfoStorage } from '../../intents/node/testIntent/testInfoStorage';
import { ILinkifyService, LinkifyService } from '../../linkify/common/linkifyService';
import { ILaunchConfigService } from '../../onboardDebug/common/launchConfigService';
import { DebugCommandToConfigConverter, IDebugCommandToConfigConverter } from '../../onboardDebug/node/commandToConfigConverter';
Expand Down Expand Up @@ -176,7 +175,6 @@ export function createExtensionTestingServices(): TestingServiceCollection {
testingServiceCollection.define(ITestProvider, new SyncDescriptor(TestProvider));
testingServiceCollection.define(INaiveChunkingService, new SyncDescriptor(NaiveChunkingService));
testingServiceCollection.define(ILinkifyService, new SyncDescriptor(LinkifyService));
testingServiceCollection.define(ITestGenInfoStorage, new SyncDescriptor(TestGenInfoStorage));
testingServiceCollection.define(IEditToolLearningService, new SyncDescriptor(EditToolLearningService));
testingServiceCollection.define(IDebugCommandToConfigConverter, new SyncDescriptor(DebugCommandToConfigConverter));
testingServiceCollection.define(ILaunchConfigService, new SyncDescriptor(LaunchConfigService));
Expand Down
2 changes: 1 addition & 1 deletion extensions/copilot/src/platform/parser/node/parserImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Parser = require('web-tree-sitter');
export { _getDocumentableNodeIfOnIdentifier, _getNodeToDocument, NodeToDocumentContext } from './docGenParsing';
export { _dispose } from './parserWithCaching';
export { _getNodeMatchingSelection } from './selectionParsing';
export { _findLastTest, _getTestableNode, _getTestableNodes } from './testGenParsing';
export { _findLastTest } from './testGenParsing';

function queryCoarseScopes(language: WASMLanguage, root: Parser.SyntaxNode): Parser.QueryMatch[] {
const queries = coarseScopesQuery[language];
Expand Down
6 changes: 0 additions & 6 deletions extensions/copilot/src/platform/parser/node/parserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { TextDocumentSnapshot } from '../../editing/common/textDocumentSnapshot'
import { BlockNameDetail, DetailBlock, QueryMatchTree } from './chunkGroupTypes';
import { OverlayNode, TreeSitterExpressionInfo, TreeSitterOffsetRange, TreeSitterPointRange } from './nodes';
import type * as parser from './parserImpl';
import { TestableNode } from './testGenParsing';
import { WASMLanguage } from './treeSitterLanguages';

export const IParserService = createServiceIdentifier<IParserService>('IParserService');
Expand Down Expand Up @@ -60,11 +59,6 @@ export interface TreeSitterAST {
* @param range The range to document.
*/
getDocumentableNodeIfOnIdentifier(range: TreeSitterOffsetRange): Promise<{ identifier: string; nodeRange?: TreeSitterOffsetRange } | undefined>;
/**
* @param range The range to test.
*/
getTestableNode(range: TreeSitterOffsetRange): Promise<TestableNode | null>;
getTestableNodes(): Promise<TestableNode[] | null>;
/**
* Starting from the smallest AST node that wraps `selection` and climbs up the AST until it sees a "documentable" node.
* See {@link isDocumentableNode} for definition of a "documentable" node.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export class ParserServiceImpl implements IParserService {
getTypeReferences: (selection: TreeSitterOffsetRange) => parserProxy._getTypeReferences(wasmLanguage, source, selection),
getSymbols: (selection: TreeSitterOffsetRange) => parserProxy._getSymbols(wasmLanguage, source, selection),
getDocumentableNodeIfOnIdentifier: (range: TreeSitterOffsetRange) => parserProxy._getDocumentableNodeIfOnIdentifier(wasmLanguage, source, range),
getTestableNode: (range: TreeSitterOffsetRange) => parserProxy._getTestableNode(wasmLanguage, source, range),
getTestableNodes: () => parserProxy._getTestableNodes(wasmLanguage, source),
getNodeToExplain: (range: TreeSitterOffsetRange) => parserProxy._getNodeToExplain(wasmLanguage, source, range),
getNodeToDocument: (range: TreeSitterOffsetRange) => parserProxy._getNodeToDocument(wasmLanguage, source, range),
getFineScopes: (selection: TreeSitterOffsetRange) => parserProxy._getFineScopes(wasmLanguage, source, selection),
Expand Down
Loading
Loading