pull-pylance-with-pyright-1.1.367-9475931426 (#8123)

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rich Chiodo <rchiodo@users.noreply.github.com>
This commit is contained in:
PylanceBot 2024-06-12 11:02:27 -07:00 committed by GitHub
parent 63e0876cff
commit 5d77369056
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 500 additions and 417 deletions

View File

@ -22,6 +22,7 @@ import { DiagnosticLevel } from '../common/configOptions';
import { assert, assertNever, fail } from '../common/debug';
import { CreateTypeStubFileAction, Diagnostic } from '../common/diagnostic';
import { DiagnosticRule } from '../common/diagnosticRules';
import { DocStringService } from '../common/docStringService';
import { stripFileExtension } from '../common/pathUtils';
import { convertTextRangeToRange } from '../common/positionUtils';
import { TextRange, getEmptyRange } from '../common/textRange';
@ -250,7 +251,11 @@ export class Binder extends ParseTreeWalker {
// the current function.
private _codeFlowComplexity = 0;
constructor(fileInfo: AnalyzerFileInfo, private _moduleSymbolOnly = false) {
constructor(
fileInfo: AnalyzerFileInfo,
private _docStringService: DocStringService,
private _moduleSymbolOnly = false
) {
super();
this._fileInfo = fileInfo;

View File

@ -9,11 +9,6 @@
* (https://www.python.org/dev/peps/pep-0257/).
*/
// Cleans the a docstring as inspect.cleandoc does.
export function cleanDocString(rawString: string): string {
return cleanAndSplitDocString(rawString).join('\n');
}
export function cleanAndSplitDocString(rawString: string): string[] {
// Remove carriage returns and replace tabs.
const unescaped = rawString.replace(/\r/g, '').replace(/\t/g, ' ');

View File

@ -17,7 +17,6 @@ import { assert } from '../common/debug';
import { Diagnostic, DiagnosticCategory, TaskListToken, convertLevelToCategory } from '../common/diagnostic';
import { DiagnosticRule } from '../common/diagnosticRules';
import { DiagnosticSink, TextRangeDiagnosticSink } from '../common/diagnosticSink';
import { ServiceProvider } from '../common/extensibility';
import { FileSystem } from '../common/fileSystem';
import { LogTracker, getPathForLogging } from '../common/logTracker';
import { stripFileExtension } from '../common/pathUtils';
@ -47,6 +46,8 @@ import { SourceMapper } from './sourceMapper';
import { SymbolTable } from './symbol';
import { TestWalker } from './testWalker';
import { TypeEvaluator } from './typeEvaluatorTypes';
import '../common/serviceProviderExtensions';
import { ServiceProvider } from '../common/serviceProvider';
// Limit the number of import cycles tracked per source file.
const _maxImportCyclesPerFile = 4;
@ -833,7 +834,11 @@ export class SourceFile {
);
AnalyzerNodeInfo.setFileInfo(this._writableData.parserOutput!.parseTree, fileInfo);
const binder = new Binder(fileInfo, configOptions.indexGenerationMode);
const binder = new Binder(
fileInfo,
this.serviceProvider.docStringService(),
configOptions.indexGenerationMode
);
this._writableData.isBindingInProgress = true;
binder.bindModule(this._writableData.parserOutput!.parseTree);

View File

@ -182,6 +182,13 @@ export function getVariableInStubFileDocStrings(decl: VariableDeclaration, sourc
return docStrings;
}
export function isBuiltInModule(uri: Uri | undefined) {
if (uri) {
return uri.getPath().includes('typeshed-fallback/stdlib');
}
return false;
}
export function getModuleDocStringFromModuleNodes(modules: ModuleNode[]): string | undefined {
for (const module of modules) {
if (module.statements) {

View File

@ -0,0 +1,50 @@
/*
* docStringService.ts
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*
* Interface for service that parses docstrings and converts them to other formats.
*/
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
import { extractParameterDocumentation } from '../analyzer/docStringUtils';
export interface DocStringService {
convertDocStringToPlainText(docString: string): string;
convertDocStringToMarkdown(docString: string, forceLiteral?: boolean): string;
extractParameterDocumentation(
functionDocString: string,
paramName: string,
forceLiteral?: boolean
): string | undefined;
clone(): DocStringService;
}
export namespace DocStringService {
export function is(value: any): value is DocStringService {
return (
!!value.convertDocStringToMarkdown &&
!!value.convertDocStringToPlainText &&
!!value.extractParameterDocumentation
);
}
}
export class PyrightDocStringService implements DocStringService {
convertDocStringToPlainText(docString: string): string {
return convertDocStringToPlainText(docString);
}
convertDocStringToMarkdown(docString: string): string {
return convertDocStringToMarkdown(docString);
}
extractParameterDocumentation(functionDocString: string, paramName: string): string | undefined {
return extractParameterDocumentation(functionDocString, paramName);
}
clone() {
// No need to clone, no internal state
return this;
}
}

View File

@ -12,6 +12,7 @@ import { Workspace, WorkspaceFolder } from '../workspaceFactory';
import { Uri } from './uri/uri';
import { isRootedDiskPath, normalizeSlashes } from './pathUtils';
import { ServiceKeys } from './serviceKeys';
import { escapeRegExp } from './stringUtils';
export function resolvePathWithEnvVariables(
workspace: Workspace,
@ -65,7 +66,8 @@ export function expandPathVariables(path: string, rootPath: Uri, workspaces: Wor
continue;
}
const ws_regexp = RegExp(`\\$\\{workspaceFolder:${workspace.workspaceName}\\}`, 'g');
const escapedWorkspaceName = escapeRegExp(workspace.workspaceName);
const ws_regexp = RegExp(`\\$\\{workspaceFolder:${escapedWorkspaceName}\\}`, 'g');
path = path.replace(ws_regexp, workspace.rootUri.getPath());
}
if (process.env.HOME !== undefined) {

View File

@ -22,7 +22,7 @@ import { ParseFileResults, ParserOutput } from '../parser/parser';
import { ConfigOptions } from './configOptions';
import { ConsoleInterface } from './console';
import { ReadOnlyFileSystem } from './fileSystem';
import { GroupServiceKey, ServiceKey } from './serviceProvider';
import { ServiceProvider } from './serviceProvider';
import { Range } from './textRange';
import { Uri } from './uri/uri';
@ -64,14 +64,6 @@ export interface SourceFileInfo {
readonly shadowedBy: readonly SourceFileInfo[];
}
export interface ServiceProvider {
tryGet<T>(key: ServiceKey<T>): T | undefined;
tryGet<T>(key: GroupServiceKey<T>): readonly T[] | undefined;
get<T>(key: ServiceKey<T>): T;
get<T>(key: GroupServiceKey<T>): readonly T[];
}
// Readonly wrapper around a Program. Makes sure it doesn't mutate the program.
export interface ProgramView {
readonly id: string;

View File

@ -15,7 +15,6 @@ import { DiagnosticSeverityOverridesMap } from './commandLineOptions';
import { SignatureDisplayType } from './configOptions';
import { ConsoleInterface, LogLevel } from './console';
import { TaskListToken } from './diagnostic';
import * as ext from './extensibility';
import { FileSystem } from './fileSystem';
import { FileWatcherHandler } from './fileWatcher';
import { ServiceProvider } from './serviceProvider';
@ -124,7 +123,7 @@ export interface LanguageServerBaseInterface {
readonly console: ConsoleInterface;
readonly window: WindowInterface;
readonly supportAdvancedEdits: boolean;
readonly serviceProvider: ext.ServiceProvider;
readonly serviceProvider: ServiceProvider;
createBackgroundAnalysis(serviceId: string): BackgroundAnalysisBase | undefined;
reanalyze(): void;

View File

@ -11,6 +11,7 @@ import { ISourceFileFactory } from '../analyzer/programTypes';
import { SupportPartialStubs } from '../pyrightFileSystem';
import { CaseSensitivityDetector } from './caseSensitivityDetector';
import { ConsoleInterface } from './console';
import { DocStringService } from './docStringService';
import {
DebugInfoInspector,
StatusMutationListener,
@ -32,4 +33,5 @@ export namespace ServiceKeys {
export const cacheManager = new ServiceKey<CacheManager>();
export const debugInfoInspector = new ServiceKey<DebugInfoInspector>();
export const caseSensitivityDetector = new ServiceKey<CaseSensitivityDetector>();
export const docStringService = new ServiceKey<DocStringService>();
}

View File

@ -92,6 +92,8 @@ export class ServiceProvider {
this._container.forEach((value, key) => {
if (key.kind === 'group') {
serviceProvider._container.set(key, [...(value ?? [])]);
} else if (value.clone !== undefined) {
serviceProvider._container.set(key, value.clone());
} else {
serviceProvider._container.set(key, value);
}

View File

@ -12,11 +12,11 @@ import { SupportPartialStubs } from '../pyrightFileSystem';
import { ServiceKeys } from './serviceKeys';
import { CaseSensitivityDetector } from './caseSensitivityDetector';
import { ConsoleInterface } from './console';
import { ServiceProvider as ReadOnlyServiceProvider } from './extensibility';
import { FileSystem, TempFile } from './fileSystem';
import { LogTracker } from './logTracker';
import { ServiceProvider } from './serviceProvider';
import { Uri } from './uri/uri';
import { DocStringService, PyrightDocStringService } from './docStringService';
declare module './serviceProvider' {
interface ServiceProvider {
@ -26,6 +26,7 @@ declare module './serviceProvider' {
sourceFileFactory(): ISourceFileFactory;
partialStubs(): SupportPartialStubs;
cacheManager(): CacheManager | undefined;
docStringService(): DocStringService;
}
}
@ -55,6 +56,9 @@ export function createServiceProvider(...services: any): ServiceProvider {
if (CacheManager.is(service)) {
sp.add(ServiceKeys.cacheManager, service);
}
if (DocStringService.is(service)) {
sp.add(ServiceKeys.docStringService, service);
}
});
return sp;
}
@ -76,6 +80,11 @@ ServiceProvider.prototype.sourceFileFactory = function () {
return result || DefaultSourceFileFactory;
};
ServiceProvider.prototype.docStringService = function () {
const result = this.tryGet(ServiceKeys.docStringService);
return result || new PyrightDocStringService();
};
ServiceProvider.prototype.cacheManager = function () {
const result = this.tryGet(ServiceKeys.cacheManager);
return result;
@ -83,7 +92,7 @@ ServiceProvider.prototype.cacheManager = function () {
const DefaultSourceFileFactory: ISourceFileFactory = {
createSourceFile(
serviceProvider: ReadOnlyServiceProvider,
serviceProvider: ServiceProvider,
fileUri: Uri,
moduleName: string,
isThirdPartyImport: boolean,

View File

@ -166,3 +166,7 @@ export function truncate(text: string, maxLength: number) {
}
return text;
}
export function escapeRegExp(text: string) {
return text.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
}

View File

@ -15,9 +15,9 @@ import {
stripTrailingDirectorySeparator,
} from '../pathUtils';
import { Uri } from './uri';
import { ServiceProvider } from '../extensibility';
import { ServiceKeys } from '../serviceKeys';
import { CaseSensitivityDetector } from '../caseSensitivityDetector';
import { ServiceProvider } from '../serviceProvider';
export interface FileSpec {
// File specs can contain wildcard characters (**, *, ?). This
@ -149,7 +149,7 @@ export function tryStat(fs: ReadOnlyFileSystem, uri: Uri): Stats | undefined {
export function tryRealpath(fs: ReadOnlyFileSystem, uri: Uri): Uri | undefined {
try {
return fs.realCasePath(uri);
return fs.realpathSync(uri);
} catch (e: any) {
return undefined;
}

View File

@ -565,11 +565,11 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.connection.onShutdown(async (token) => this.onShutdown(token));
}
protected initialize(
protected async initialize(
params: InitializeParams,
supportedCommands: string[],
supportedCodeActions: string[]
): InitializeResult {
): Promise<InitializeResult> {
if (params.locale) {
setLocaleOverride(params.locale);
}
@ -904,6 +904,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
this.client.hasSignatureLabelOffsetCapability,
this.client.hasActiveParameterCapability,
params.context,
program.serviceProvider.docStringService(),
token
).getSignatureHelp();
}, token);

View File

@ -29,7 +29,6 @@ import {
VariableDeclaration,
} from '../analyzer/declaration';
import { isDefinedInFile } from '../analyzer/declarationUtils';
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
import { ImportedModuleDescriptor, ImportResolver } from '../analyzer/importResolver';
import { ImportResult } from '../analyzer/importResult';
import { getParameterListDetails, ParameterKind } from '../analyzer/parameterUtils';
@ -41,7 +40,7 @@ import { Symbol, SymbolTable } from '../analyzer/symbol';
import * as SymbolNameUtils from '../analyzer/symbolNameUtils';
import { getLastTypedDeclarationForSymbol, isVisibleExternally } from '../analyzer/symbolUtils';
import { getTypedDictMembersForClass } from '../analyzer/typedDicts';
import { getModuleDocStringFromUris } from '../analyzer/typeDocStringUtils';
import { getModuleDocStringFromUris, isBuiltInModule } from '../analyzer/typeDocStringUtils';
import { CallSignatureInfo, TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
import { printLiteralValue } from '../analyzer/typePrinter';
import {
@ -127,6 +126,7 @@ import {
} from './completionProviderUtils';
import { DocumentSymbolCollector } from './documentSymbolCollector';
import { getAutoImportText, getDocumentationPartsForTypeAndDecl } from './tooltipUtils';
import '../common/serviceProviderExtensions';
namespace Keywords {
const base: string[] = [
@ -351,22 +351,24 @@ export class CompletionProvider {
Uri.parse(completionItemData.moduleUri, this.program.serviceProvider)
)
) {
const documentation = getModuleDocStringFromUris(
[Uri.parse(completionItemData.moduleUri, this.program.serviceProvider)],
this.sourceMapper
);
const moduleUri = Uri.parse(completionItemData.moduleUri, this.program.serviceProvider);
const documentation = getModuleDocStringFromUris([moduleUri], this.sourceMapper);
if (!documentation) {
return;
}
if (this.options.format === MarkupKind.Markdown) {
const markdownString = convertDocStringToMarkdown(documentation);
const markdownString = this.program.serviceProvider
.docStringService()
.convertDocStringToMarkdown(documentation, isBuiltInModule(moduleUri));
completionItem.documentation = {
kind: MarkupKind.Markdown,
value: markdownString,
};
} else if (this.options.format === MarkupKind.PlainText) {
const plainTextString = convertDocStringToPlainText(documentation);
const plainTextString = this.program.serviceProvider
.docStringService()
.convertDocStringToPlainText(documentation);
completionItem.documentation = {
kind: MarkupKind.PlainText,
value: plainTextString,
@ -683,9 +685,11 @@ export class CompletionProvider {
if (this.options.format === MarkupKind.Markdown || this.options.format === MarkupKind.PlainText) {
this.itemToResolve.documentation = getCompletionItemDocumentation(
this.program.serviceProvider,
typeDetail,
documentation,
this.options.format
this.options.format,
primaryDecl
);
} else {
fail(`Unsupported markup type: ${this.options.format}`);
@ -966,7 +970,9 @@ export class CompletionProvider {
if (detail?.documentation) {
markdownString += '---\n';
markdownString += convertDocStringToMarkdown(detail.documentation);
markdownString += this.program.serviceProvider
.docStringService()
.convertDocStringToMarkdown(detail.documentation, isBuiltInModule(detail.moduleUri));
}
markdownString = markdownString.trimEnd();
@ -993,7 +999,9 @@ export class CompletionProvider {
}
if (detail?.documentation) {
plainTextString += '\n' + convertDocStringToPlainText(detail.documentation);
plainTextString +=
'\n' +
this.program.serviceProvider.docStringService().convertDocStringToPlainText(detail.documentation);
}
plainTextString = plainTextString.trimEnd();

View File

@ -9,7 +9,6 @@
import { InsertTextFormat, MarkupContent, MarkupKind, TextEdit } from 'vscode-languageserver-types';
import { Declaration, DeclarationType } from '../analyzer/declaration';
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
import { isProperty } from '../analyzer/typeUtils';
import {
@ -28,6 +27,8 @@ import { SignatureDisplayType } from '../common/configOptions';
import { TextEditAction } from '../common/editAction';
import { Uri } from '../common/uri/uri';
import { getToolTipForType } from './tooltipUtils';
import { ServiceProvider } from '../common/serviceProvider';
import { isBuiltInModule } from '../analyzer/typeDocStringUtils';
export interface Edits {
format?: InsertTextFormat;
@ -152,16 +153,20 @@ export function getTypeDetail(
}
export function getCompletionItemDocumentation(
serviceProvider: ServiceProvider,
typeDetail: string | undefined,
documentation: string | undefined,
markupKind: MarkupKind
markupKind: MarkupKind,
declaration: Declaration | undefined
): MarkupContent | undefined {
if (markupKind === MarkupKind.Markdown) {
let markdownString = '```python\n' + typeDetail + '\n```\n';
if (documentation) {
markdownString += '---\n';
markdownString += convertDocStringToMarkdown(documentation);
markdownString += serviceProvider
.docStringService()
.convertDocStringToMarkdown(documentation, isBuiltInModule(declaration?.uri));
}
markdownString = markdownString.trimEnd();
@ -175,7 +180,7 @@ export function getCompletionItemDocumentation(
if (documentation) {
plainTextString += '\n';
plainTextString += convertDocStringToPlainText(documentation);
plainTextString += serviceProvider.docStringService().convertDocStringToPlainText(documentation);
}
plainTextString = plainTextString.trimEnd();

View File

@ -27,13 +27,14 @@ import { TypeCategory, isOverloadedFunction } from '../analyzer/types';
import { throwIfCancellationRequested } from '../common/cancellationUtils';
import { appendArray } from '../common/collectionUtils';
import { isDefined } from '../common/core';
import { ProgramView, ServiceProvider } from '../common/extensibility';
import { ProgramView } from '../common/extensibility';
import { convertPositionToOffset } from '../common/positionUtils';
import { ServiceKeys } from '../common/serviceKeys';
import { DocumentRange, Position, rangesAreEqual } from '../common/textRange';
import { Uri } from '../common/uri/uri';
import { ParseNode, ParseNodeType } from '../parser/parseNodes';
import { ParseFileResults } from '../parser/parser';
import { ServiceProvider } from '../common/serviceProvider';
export enum DefinitionFilter {
All = 'all',

View File

@ -17,7 +17,6 @@ import {
VariableDeclaration,
isUnresolvedAliasDeclaration,
} from '../analyzer/declaration';
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
import * as ParseTreeUtils from '../analyzer/parseTreeUtils';
import { SourceMapper } from '../analyzer/sourceMapper';
import { PrintTypeOptions, TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
@ -50,6 +49,8 @@ import {
getToolTipForType,
getTypeForToolTip,
} from './tooltipUtils';
import { ServiceProvider } from '../common/serviceProvider';
import { isBuiltInModule } from '../analyzer/typeDocStringUtils';
export interface HoverTextPart {
python?: boolean;
@ -91,13 +92,21 @@ export function convertHoverResults(hoverResults: HoverResults | null, format: M
};
}
export function addDocumentationResultsPart(docString: string | undefined, format: MarkupKind, parts: HoverTextPart[]) {
export function addDocumentationResultsPart(
serviceProvider: ServiceProvider,
docString: string | undefined,
format: MarkupKind,
parts: HoverTextPart[],
resolvedDecl: Declaration | undefined
) {
if (!docString) {
return;
}
if (format === MarkupKind.Markdown) {
const markDown = convertDocStringToMarkdown(docString);
const markDown = serviceProvider
.docStringService()
.convertDocStringToMarkdown(docString, isBuiltInModule(resolvedDecl?.uri));
if (parts.length > 0 && markDown.length > 0) {
parts.push({ text: '---\n' });
@ -108,7 +117,7 @@ export function addDocumentationResultsPart(docString: string | undefined, forma
}
if (format === MarkupKind.PlainText) {
parts.push({ text: convertDocStringToPlainText(docString), python: false });
parts.push({ text: serviceProvider.docStringService().convertDocStringToPlainText(docString), python: false });
return;
}
@ -495,7 +504,7 @@ export class HoverProvider {
name,
});
addDocumentationResultsPart(docString, this._format, parts);
addDocumentationResultsPart(this._program.serviceProvider, docString, this._format, parts, resolvedDecl);
return !!docString;
}

View File

@ -20,8 +20,6 @@ import {
SignatureInformation,
} from 'vscode-languageserver';
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
import { extractParameterDocumentation } from '../analyzer/docStringUtils';
import * as ParseTreeUtils from '../analyzer/parseTreeUtils';
import { getCallNodeAndActiveParameterIndex } from '../analyzer/parseTreeUtils';
import { SourceMapper } from '../analyzer/sourceMapper';
@ -35,6 +33,9 @@ import { Uri } from '../common/uri/uri';
import { CallNode, NameNode, ParseNodeType } from '../parser/parseNodes';
import { ParseFileResults } from '../parser/parser';
import { getDocumentationPartsForTypeAndDecl, getFunctionDocStringFromType } from './tooltipUtils';
import { DocStringService } from '../common/docStringService';
import { getFileInfo } from '../analyzer/analyzerNodeInfo';
import { isBuiltInModule } from '../analyzer/typeDocStringUtils';
export class SignatureHelpProvider {
private readonly _parseResults: ParseFileResults | undefined;
@ -48,6 +49,7 @@ export class SignatureHelpProvider {
private _hasSignatureLabelOffsetCapability: boolean,
private _hasActiveParameterCapability: boolean,
private _context: SignatureHelpContext | undefined,
private _docStringService: DocStringService,
private _token: CancellationToken
) {
this._parseResults = this._program.getParseResults(this._fileUri);
@ -224,6 +226,7 @@ export class SignatureHelpProvider {
const functionDocString =
getFunctionDocStringFromType(functionType, this._sourceMapper, this._evaluator) ??
this._getDocStringFromCallNode(callNode);
const fileInfo = getFileInfo(callNode);
let label = '(';
let activeParameter: number | undefined;
@ -241,7 +244,7 @@ export class SignatureHelpProvider {
startOffset: label.length,
endOffset: label.length + paramString.length,
text: paramString,
documentation: extractParameterDocumentation(functionDocString || '', paramName),
documentation: this._docStringService.extractParameterDocumentation(functionDocString || '', paramName),
});
// Name match for active parameter. The set of parameters from the function
@ -275,12 +278,15 @@ export class SignatureHelpProvider {
if (this._format === MarkupKind.Markdown) {
sigInfo.documentation = {
kind: MarkupKind.Markdown,
value: convertDocStringToMarkdown(functionDocString),
value: this._docStringService.convertDocStringToMarkdown(
functionDocString,
isBuiltInModule(fileInfo?.fileUri)
),
};
} else {
sigInfo.documentation = {
kind: MarkupKind.PlainText,
value: convertDocStringToPlainText(functionDocString),
value: this._docStringService.convertDocStringToPlainText(functionDocString),
};
}
}

View File

@ -156,6 +156,7 @@
"enumClassOverride": "Třída výčtu {name} je konečná a nemůže být podtřídou",
"enumMemberDelete": "Člen výčtu {name} se nedá odstranit.",
"enumMemberSet": "Člen výčtu {name} se nedá přiřadit.",
"enumMemberTypeAnnotation": "Poznámky typu nejsou pro členy výčtu povolené",
"exceptionGroupIncompatible": "Syntaxe skupiny výjimek (except*) vyžaduje Python 3.11 nebo novější",
"exceptionTypeIncorrect": "„{type}“ se neodvozuje od BaseException",
"exceptionTypeNotClass": "{type} není platná třída výjimky",
@ -624,7 +625,7 @@
"yieldFromIllegal": "Použití příkazu yield from vyžaduje Python 3.3 nebo novější",
"yieldFromOutsideAsync": "yield from není v asynchronní funkci povoleno",
"yieldOutsideFunction": "„yield“ není povoleno mimo funkci nebo lambdu",
"yieldWithinComprehension": "yield není povolen uvnitř seznamu porozumění",
"yieldWithinComprehension": "yield není povolené uvnitř porozumění",
"zeroCaseStatementsFound": "Výraz shody obsahovat alespoň jeden výraz velikosti písmen",
"zeroLengthTupleNotAllowed": "Řazená kolekce členů s nulovou délkou není v tomto kontextu povolená"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "Die Enumerationsklasse \"{name}\" ist final und kann nicht in eine Unterklasse aufgenommen werden.",
"enumMemberDelete": "Das Enumerationselement \"{name}\" kann nicht gelöscht werden.",
"enumMemberSet": "Das Enumerationselement \"{name}\" kann nicht zugewiesen werden.",
"enumMemberTypeAnnotation": "Typanmerkungen sind für Enumerationsmember nicht zulässig",
"exceptionGroupIncompatible": "Die Ausnahmegruppensyntax (\"except*\") erfordert Python 3.11 oder höher.",
"exceptionTypeIncorrect": "\"{type}\" ist nicht von BaseException abgeleitet.",
"exceptionTypeNotClass": "\"{type}\" ist keine gültige Ausnahmeklasse.",
@ -624,7 +625,7 @@
"yieldFromIllegal": "Die Verwendung von \"yield from\" erfordert Python 3.3 oder höher.",
"yieldFromOutsideAsync": "\"yield from\" ist in einer asynchronen Funktion nicht zulässig.",
"yieldOutsideFunction": "\"yield\" ist außerhalb einer Funktion oder eines Lambdas nicht zulässig.",
"yieldWithinComprehension": "\"yield\" ist innerhalb eines Listenverständnisses nicht zulässig.",
"yieldWithinComprehension": "„yield“ ist innerhalb eines Verständnisses nicht zulässig",
"zeroCaseStatementsFound": "Die match-Anweisung muss mindestens eine case-Anweisung enthalten",
"zeroLengthTupleNotAllowed": "Ein Tupel mit der Länge Null ist in diesem Kontext nicht zulässig."
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "La clase Enum \"{name}\" es final y no puede ser subclasificada",
"enumMemberDelete": "No se puede eliminar el miembro de enumeración \"{name}\"",
"enumMemberSet": "No se puede asignar el miembro de enumeración \"{name}\"",
"enumMemberTypeAnnotation": "No se permiten anotaciones de tipo para miembros de enumeración",
"exceptionGroupIncompatible": "La sintaxis de grupo de excepciones (\"except*\") requiere Python 3.11 o posterior.",
"exceptionTypeIncorrect": "\"{type}\" no se deriva de BaseException",
"exceptionTypeNotClass": "\"{type}\" no es una clase de excepción válida",

View File

@ -156,6 +156,7 @@
"enumClassOverride": "La classe Enum « {name} » est finale et ne peut pas être sous-classée",
"enumMemberDelete": "Le membre enum « {name} » ne peut pas être supprimé",
"enumMemberSet": "Le membre enum « {name} » ne peut pas être affecté",
"enumMemberTypeAnnotation": "Les annotations de type ne sont pas autorisées pour les membres enum",
"exceptionGroupIncompatible": "La syntaxe du groupe dexceptions (« except* ») nécessite Python 3.11 ou version ultérieure",
"exceptionTypeIncorrect": "\"{type}\" ne dérive pas de BaseException",
"exceptionTypeNotClass": "« {type} » nest pas une classe dexception valide",
@ -624,7 +625,7 @@
"yieldFromIllegal": "Lutilisation de « yield from » nécessite Python 3.3 ou version ultérieure",
"yieldFromOutsideAsync": "« yield from » non autorisé dans une fonction asynchrone",
"yieldOutsideFunction": "\"rendement\" non autorisé en dehors d'une fonction ou d'un lambda",
"yieldWithinComprehension": yield » non autorisé dans une compréhension de liste",
"yieldWithinComprehension":  yield » nest pas autorisé dans une compréhension de liste",
"zeroCaseStatementsFound": "L'instruction de correspondance doit inclure au moins une instruction case",
"zeroLengthTupleNotAllowed": "Le tuple de longueur nulle nest pas autorisé dans ce contexte"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "La classe di enumerazione \"{name}\" è finale e non può essere sottoclassata",
"enumMemberDelete": "Non è possibile eliminare il membro di enumerazione \"{name}\"",
"enumMemberSet": "Non è possibile assegnare il membro di enumerazione \"{name}\"",
"enumMemberTypeAnnotation": "Le annotazioni di tipo non sono consentite per i membri di enumerazione",
"exceptionGroupIncompatible": "La sintassi del gruppo di eccezioni (\"except*\") richiede Python 3.11 o versione successiva",
"exceptionTypeIncorrect": "\"{type}\" non deriva da BaseException",
"exceptionTypeNotClass": "\"{type}\" non è una classe di eccezione valida",
@ -624,7 +625,7 @@
"yieldFromIllegal": "L'uso di \"yield from\" richiede Python 3.3 o versione successiva",
"yieldFromOutsideAsync": "\"yield from\" non consentito in una funzione asincrona",
"yieldOutsideFunction": "\"yield\" non consentito all'esterno di una funzione o di un'espressione lambda",
"yieldWithinComprehension": "\"yield\" non consentito all'interno di una comprensione di elenco",
"yieldWithinComprehension": "\"yield\" non consentito all'interno di una comprensione",
"zeroCaseStatementsFound": "Listruzione Match deve includere almeno unistruzione case",
"zeroLengthTupleNotAllowed": "Tupla di lunghezza zero non è consentita in questo contesto"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "列挙型クラス \"{name}\" は最終的なクラスであり、サブクラス化できません",
"enumMemberDelete": "列挙型メンバー \"{name}\" を削除できません",
"enumMemberSet": "列挙型メンバー \"{name}\" を割り当てることはできません",
"enumMemberTypeAnnotation": "列挙型メンバーには型注釈を使用できません",
"exceptionGroupIncompatible": "例外グループの構文 (\"except*\") には Python 3.11 以降が必要です",
"exceptionTypeIncorrect": "\"{type}\" は BaseException から派生していません",
"exceptionTypeNotClass": "\"{type}\" は有効な例外クラスではありません",
@ -624,7 +625,7 @@
"yieldFromIllegal": "\"yield from\" を使用するには Python 3.3 以降が必要です",
"yieldFromOutsideAsync": "非同期関数では \"yield from\" は使用できません",
"yieldOutsideFunction": "関数またはラムダの外部では \"yield\" は許可されません",
"yieldWithinComprehension": "\"yield\" はリスト理解内では使用できません",
"yieldWithinComprehension": "\"yield\" は内包表記内では使用できません",
"zeroCaseStatementsFound": "Match ステートメントには、少なくとも 1 つの case ステートメントを含める必要があります",
"zeroLengthTupleNotAllowed": "このコンテキストでは長さ 0 のタプルは使用できません"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "열거형 클래스 \"{name}\"은(는) 최종 클래스이며 서브클래스할 수 없습니다.",
"enumMemberDelete": "열거형 멤버 \"{name}\"을(를) 삭제할 수 없음",
"enumMemberSet": "열거형 멤버 \"{name}\"을(를) 할당할 수 없음",
"enumMemberTypeAnnotation": "열거형 멤버에는 형식 주석을 사용할 수 없습니다.",
"exceptionGroupIncompatible": "예외 그룹 구문(\"except*\")에는 Python 3.11 이상이 필요합니다.",
"exceptionTypeIncorrect": "{type}’은 BaseException에서 파생되지 않습니다.",
"exceptionTypeNotClass": "\"{type}\"은(는) 올바른 예외 클래스가 아닙니다.",
@ -624,7 +625,7 @@
"yieldFromIllegal": "\"yield from\"을 사용하려면 Python 3.3 이상이 필요합니다.",
"yieldFromOutsideAsync": "비동기 함수에서는 \"yield from\"을 사용할 수 없습니다.",
"yieldOutsideFunction": "함수 또는 람다 외부에서는 yield를 사용할 수 없습니다.",
"yieldWithinComprehension": "목록 이해 내에서는 \"yield\"를 사용할 수 없습니다.",
"yieldWithinComprehension": "이해력 내에서는 \"일시 중단\"을 사용할 수 없습니다.",
"zeroCaseStatementsFound": "Match 문에는 Case 문이 하나 이상 포함되어야 합니다.",
"zeroLengthTupleNotAllowed": "길이가 0인 튜플은 이 컨텍스트에서 허용되지 않습니다."
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "Klasa wyliczenia „{name}” jest ostateczna i nie można jej podzielić na podklasy",
"enumMemberDelete": "Nie można usunąć składowej wyliczenia \"{name}\"",
"enumMemberSet": "Nie można przypisać składowej wyliczenia „{name}”",
"enumMemberTypeAnnotation": "Adnotacje typu nie są dozwolone dla elementów członkowskich wyliczenia",
"exceptionGroupIncompatible": "Składnia grupy wyjątków („except*”) wymaga języka Python w wersji 3.11 lub nowszej",
"exceptionTypeIncorrect": "Typ „{type}” nie pochodzi od parametru BaseException",
"exceptionTypeNotClass": "Typ „{type}” nie jest prawidłową klasą wyjątku",
@ -624,7 +625,7 @@
"yieldFromIllegal": "Użycie wartości „yield from” wymaga języka Python w wersji 3.3 lub nowszej",
"yieldFromOutsideAsync": "Instrukcja „yield from” jest niedozwolona w funkcji asynchronicznej",
"yieldOutsideFunction": "Instrukcja „yield” jest niedozwolona poza funkcją lub wyrażeniem lambda",
"yieldWithinComprehension": "Instrukcja „yield” nie jest dozwolona w rozumieniu listy",
"yieldWithinComprehension": "Instrukcja „yield” nie jest dozwolona w rozumieniu",
"zeroCaseStatementsFound": "Instrukcja dopasowania musi zawierać co najmniej jedną instrukcję dotyczącą wielkości liter",
"zeroLengthTupleNotAllowed": "Krotka o zerowej długości jest niedozwolona w tym kontekście"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "A classe Enum \"{name}\" é final e não pode ser subclasse",
"enumMemberDelete": "O membro enumerado \"{name}\" não pode ser excluído",
"enumMemberSet": "O membro enumerado \"{name}\" não pode ser atribuído",
"enumMemberTypeAnnotation": "Anotações de tipo não são permitidas para membros de enumeração",
"exceptionGroupIncompatible": "A sintaxe do grupo de exceção (\"exceto*\") requer o Python 3.11 ou mais recente",
"exceptionTypeIncorrect": "\"{type}\" não deriva de BaseException",
"exceptionTypeNotClass": "\"{type}\" não é uma classe de exceção válida",
@ -624,7 +625,7 @@
"yieldFromIllegal": "O uso de \"yield from\" requer o Python 3.3 ou mais recente",
"yieldFromOutsideAsync": "\"yield from\" não é permitido em uma função assíncrona",
"yieldOutsideFunction": "\"yield\" não permitido fora de uma função ou lambda",
"yieldWithinComprehension": "\"yield\" não é permitido dentro de uma compreensão de lista",
"yieldWithinComprehension": "\"yield\" não é permitido dentro de uma compreensão",
"zeroCaseStatementsFound": "A instrução Match deve incluir pelo menos uma instrução case",
"zeroLengthTupleNotAllowed": "Tupla de comprimento zero não é permitida neste contexto"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "[2JsL1][นั้Ëñµm çlæss \"{ñæmë}\" ïs fïñæl æñð çæññøt þë sµþçlæssëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]",
"enumMemberDelete": "[5wmRY][นั้Ëñµm mëmþër \"{ñæmë}\" çæññøt þë ðëlëtëðẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]",
"enumMemberSet": "[mBLro][นั้Ëñµm mëmþër \"{ñæmë}\" çæññøt þë æssïgñëðẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]",
"enumMemberTypeAnnotation": "[z8FaL][นั้Tÿpë æññøtætïøñs ærë ñøt ælløwëð før ëñµm mëmþërsẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]",
"exceptionGroupIncompatible": "[d0SLP][นั้Ëxçëptïøñ grøµp sÿñtæx (\"ëxçëpt*\") rëqµïrës Pÿthøñ 3.11 ør ñëwërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]",
"exceptionTypeIncorrect": "[G7AZt][นั้\"{tÿpë}\" ðøës ñøt ðërïvë frøm ßæsëËxçëptïøñẤğ倪İЂҰक्र्तिृまẤğ倪นั้ढूँ]",
"exceptionTypeNotClass": "[v1FmY][นั้\"{tÿpë}\" ïs ñøt æ vælïð ëxçëptïøñ çlæssẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]",
@ -624,7 +625,7 @@
"yieldFromIllegal": "[DkXto][นั้Üsë øf \"ÿïëlð frøm\" rëqµïrës Pÿthøñ 3.3 ør ñëwërẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]",
"yieldFromOutsideAsync": "[ZONEz][นั้\"ÿïëlð frøm\" ñøt ælløwëð ïñ æñ æsÿñç fµñçtïøñẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]",
"yieldOutsideFunction": "[2lDBQ][นั้\"ÿïëlð\" ñøt ælløwëð øµtsïðë øf æ fµñçtïøñ ør læmþðæẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]",
"yieldWithinComprehension": "[3Rv4s][นั้\"ÿïëlð\" ñøt ælløwëð ïñsïðë æ lïst çømprëhëñsïøñẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]",
"yieldWithinComprehension": "[yALS5][นั้\"ÿïëlð\" ñøt ælløwëð ïñsïðë æ çømprëhëñsïøñẤğ倪İЂҰक्र्तिृまẤğ倪นั้ढूँ]",
"zeroCaseStatementsFound": "[ArU3j][นั้Mætçh stætëmëñt mµst ïñçlµðë æt lëæst øñë çæsë stætëmëñtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]",
"zeroLengthTupleNotAllowed": "[3gVpF][นั้Zërø-lëñgth tµplë ïs ñøt ælløwëð ïñ thïs çøñtëxtẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "Перечислимый класс \"{name}\" является окончательным и не может иметь производных классов",
"enumMemberDelete": "Не удается удалить элемент перечисления \"{name}\"",
"enumMemberSet": "Не удается назначить элемент перечисления \"{name}\"",
"enumMemberTypeAnnotation": "Аннотации типов не разрешены для элементов перечисления",
"exceptionGroupIncompatible": "Синтаксис группы исключений (\"except*\") можно использовать в Python версии не ранее 3.11",
"exceptionTypeIncorrect": "\"{type}\" не является производным от BaseException",
"exceptionTypeNotClass": "\"{type}\" не является допустимым классом исключений",
@ -624,7 +625,7 @@
"yieldFromIllegal": "\"Yield from\" можно использовать в Python версии не ниже 3.3",
"yieldFromOutsideAsync": "\"yield from\" не допускается в асинхронной функции",
"yieldOutsideFunction": "\"yield\" не допускается за пределами функции или лямбда-выражении",
"yieldWithinComprehension": "\"yield\" не допускается внутри понимания списка",
"yieldWithinComprehension": "\"yield\" не допускается внутри понимания",
"zeroCaseStatementsFound": "Операторе match должен включать по крайней мере один оператор case",
"zeroLengthTupleNotAllowed": "Кортеж нулевой длины не допускается в этом контексте"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "\"{name}\" sabit listesi sınıfı final niteliğinde ve alt sınıf olamaz",
"enumMemberDelete": "Sabit liste üyesi \"{name}\" silinemiyor",
"enumMemberSet": "Sabit liste üyesi \"{name}\" atanamıyor",
"enumMemberTypeAnnotation": "Sabit listesi üyeleri için tür ek açıklamalarına izin verilmiyor",
"exceptionGroupIncompatible": "Özel durum grubu söz dizimi (\"except*\") için Python 3.11 veya daha yeni bir sürümü gerekiyor",
"exceptionTypeIncorrect": "\"{type}\", BaseException türevi değil",
"exceptionTypeNotClass": "\"{type}\" geçerli bir özel durum sınıfı değil",
@ -624,7 +625,7 @@
"yieldFromIllegal": "\"yield from\" kullanımı için Python 3.3 veya daha yeni bir sürümü gerekiyor",
"yieldFromOutsideAsync": "Zaman uyumsuz bir işlevde \"yield from\" öğesine izin verilmez",
"yieldOutsideFunction": "\"yield\", işlev veya lambda dışında kullanılamaz",
"yieldWithinComprehension": "Liste anlama içinde \"yield\" kullanılamaz",
"yieldWithinComprehension": "Bir anlama içinde “yield” kullanılamaz",
"zeroCaseStatementsFound": "Match deyimi en az bir case deyimi içermeli",
"zeroLengthTupleNotAllowed": "Bu bağlamda sıfır uzunluklu demete izin verilmiyor"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "枚举类“{name}”是最终类,不能为子类",
"enumMemberDelete": "无法删除枚举成员“{name}”",
"enumMemberSet": "无法分配枚举成员“{name}”",
"enumMemberTypeAnnotation": "枚举成员不允许使用类型注释",
"exceptionGroupIncompatible": "异常组语法 (\"except*\") 需要 Python 3.11 或更高版本",
"exceptionTypeIncorrect": "\"{type}\" 不是派生自 BaseException",
"exceptionTypeNotClass": "“{type}”不是有效的异常类",
@ -624,7 +625,7 @@
"yieldFromIllegal": "使用“yield from”需要 Python 3.3 或更高版本",
"yieldFromOutsideAsync": "异步函数中不允许使用“yield from”",
"yieldOutsideFunction": "不允许在函数或 lambda 之外使用“yield”",
"yieldWithinComprehension": "不允许在列表理解中使用“yield”",
"yieldWithinComprehension": "不允许在理解中使用 \"yield\"",
"zeroCaseStatementsFound": "Match 语句必须至少包含一个 case 语句",
"zeroLengthTupleNotAllowed": "此上下文中不允许使用零长度元组"
},

View File

@ -156,6 +156,7 @@
"enumClassOverride": "列舉類別 \"{name}\" 為 Final且不能設為子類別",
"enumMemberDelete": "無法刪除列舉成員 \"{name}\"",
"enumMemberSet": "無法指派列舉成員 \"{name}\"",
"enumMemberTypeAnnotation": "列舉成員不允許類型註釋",
"exceptionGroupIncompatible": "例外群組語法 (\"except*\") 需要 Python 3.11 或更新版本",
"exceptionTypeIncorrect": "\"{type}\" 不是衍生自 BaseException",
"exceptionTypeNotClass": "\"{type}\" 不是有效的例外類別",
@ -624,7 +625,7 @@
"yieldFromIllegal": "使用 \"yield from\" 需要 Python 3.3 或更新版本",
"yieldFromOutsideAsync": "非同步函式中不允許 \"yield from\"",
"yieldOutsideFunction": "在函式或 lambda 外部不允許 \"yield\"",
"yieldWithinComprehension": "清單理解內不允許 \"yield\"",
"yieldWithinComprehension": "理解內不允許 \"yield\"",
"zeroCaseStatementsFound": "Match 陳述式必須至少包含一個 case 陳述式",
"zeroLengthTupleNotAllowed": "此內容中不允許零長度 Tuple"
},

View File

@ -1,57 +0,0 @@
/*
* docStringUtils.test.ts
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*
* Unit tests for the docStringUtils.ts module.
*/
import * as assert from 'assert';
import { cleanDocString } from '../analyzer/docStringUtils';
test('EmptyDocString', () => {
const input = '';
const result = cleanDocString(input);
assert.strictEqual(result, '');
});
test('OneLine', () => {
const input = 'Simple text';
const result = cleanDocString(input);
assert.strictEqual(result, input);
});
test('OneLineLeftTrim', () => {
const input = 'Simple text';
const inputWithSpaces = ' ' + input;
const result = cleanDocString(inputWithSpaces);
assert.strictEqual(result, input);
});
test('OneLineRightTrim', () => {
const input = 'Simple text';
const inputWithSpaces = input + ' ';
const result = cleanDocString(inputWithSpaces);
assert.strictEqual(result, input);
});
test('OneLineTrimBoth', () => {
const input = 'Simple text';
const inputWithSpaces = ' ' + input + ' ';
const result = cleanDocString(inputWithSpaces);
assert.strictEqual(result, input);
});
test('TwoLines', () => {
const input = 'Simple text';
const inputWithSpaces = input + ' \n ';
const result = cleanDocString(inputWithSpaces);
assert.strictEqual(result, input);
});
test('TwoLinesIndentation', () => {
const input = 'Line 1 \n Line2 \n Line3\n Line4\n ';
const result = cleanDocString(input);
assert.strictEqual(result, 'Line 1\nLine2\n Line3\nLine4');
});

View File

@ -97,6 +97,7 @@ import {
import { TestFeatures, TestLanguageService } from './testLanguageService';
import { createVfsInfoFromFourSlashData, getMarkerByName, getMarkerName, getMarkerNames } from './testStateUtils';
import { verifyWorkspaceEdit } from './workspaceEditTestUtils';
import { PyrightDocStringService } from '../../../common/docStringService';
export interface TextChange {
span: TextRange;
@ -1126,6 +1127,7 @@ export class TestState {
/* hasSignatureLabelOffsetCapability */ true,
/* hasActiveParameterCapability */ true,
/* context */ undefined,
new PyrightDocStringService(),
CancellationToken.None
).getSignatureHelp();

View File

@ -186,6 +186,13 @@ test('getWildcardRegexPattern4', () => {
assert.ok(!regex.test(fixSeparators('//server/share/dix/foo.py')));
});
test('getWildcardRegexPattern5', () => {
const pattern = getWildcardRegexPattern('//server/share/dir++', '.');
const regex = new RegExp(pattern);
assert.ok(regex.test(fixSeparators('//server/share/dir++/foo.py')));
assert.ok(!regex.test(fixSeparators('//server/share/dix++/foo.py')));
});
test('isDirectoryWildcardPatternPresent1', () => {
const isPresent = isDirectoryWildcardPatternPresent('./**/*.py');
assert.equal(isPresent, true);

View File

@ -12,6 +12,7 @@ import { CancellationToken, MarkupKind } from 'vscode-languageserver';
import { convertOffsetToPosition } from '../common/positionUtils';
import { SignatureHelpProvider } from '../languageService/signatureHelpProvider';
import { parseAndGetTestState } from './harness/fourslash/testState';
import { PyrightDocStringService } from '../common/docStringService';
test('invalid position in format string segment', () => {
const code = `
@ -88,6 +89,7 @@ function checkSignatureHelp(code: string, expects: boolean) {
/*hasSignatureLabelOffsetCapability*/ true,
/*hasActiveParameterCapability*/ true,
/*context*/ undefined,
new PyrightDocStringService(),
CancellationToken.None
).getSignatureHelp();

View File

@ -674,6 +674,13 @@ test('getWildcardRegexPattern4', () => {
assert.ok(!regex.test('//server/share/dix/foo.py'));
});
test('getWildcardRegexPattern4', () => {
const pattern = getWildcardRegexPattern(Uri.parse('//server/share/dir++/.bar*/bid', caseDetector), '.');
const regex = new RegExp(pattern);
assert.ok(regex.test('//server/share/dir++/.bar*/bidfoo.py'));
assert.ok(!regex.test('//server/share/dix++/.bar*/bidfoo.py'));
});
test('getWildcardRoot1', () => {
const p = getWildcardRoot(Uri.parse('foo:/users/me', caseDetector), './blah/');
assert.equal(p.toString(), 'foo:/users/me/blah');

View File

@ -10,7 +10,7 @@ import { AnalyzerService } from './analyzer/service';
import { ConsoleInterface } from './common/console';
import { createDeferred } from './common/deferred';
import { Uri } from './common/uri/uri';
import { ServiceProvider } from './common/extensibility';
import { ServiceProvider } from './common/serviceProvider';
let WorkspaceFactoryIdCounter = 0;