@zzzen/pyright-internal 1.1.254 → 1.1.255
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/analyzer/aliasDeclarationUtils.ts +169 -0
- package/src/analyzer/analysis.ts +92 -0
- package/src/analyzer/analyzerFileInfo.ts +56 -0
- package/src/analyzer/analyzerNodeInfo.ts +198 -0
- package/src/analyzer/backgroundAnalysisProgram.ts +311 -0
- package/src/analyzer/binder.ts +4081 -0
- package/src/analyzer/checker.ts +5507 -0
- package/src/analyzer/circularDependency.ts +52 -0
- package/src/analyzer/codeFlowEngine.ts +1548 -0
- package/src/analyzer/codeFlowTypes.ts +266 -0
- package/src/analyzer/codeFlowUtils.ts +436 -0
- package/src/analyzer/commentUtils.ts +174 -0
- package/src/analyzer/constraintSolver.ts +926 -0
- package/src/analyzer/constructorTransform.ts +317 -0
- package/src/analyzer/dataClasses.ts +999 -0
- package/src/analyzer/declaration.ts +252 -0
- package/src/analyzer/declarationUtils.ts +238 -0
- package/src/analyzer/docStringConversion.ts +850 -0
- package/src/analyzer/docStringUtils.ts +112 -0
- package/src/analyzer/functionTransform.ts +137 -0
- package/src/analyzer/importResolver.ts +2308 -0
- package/src/analyzer/importResult.ts +98 -0
- package/src/analyzer/importStatementUtils.ts +834 -0
- package/src/analyzer/namedTuples.ts +422 -0
- package/src/analyzer/packageTypeReport.ts +108 -0
- package/src/analyzer/packageTypeVerifier.ts +1466 -0
- package/src/analyzer/parentDirectoryCache.ts +88 -0
- package/src/analyzer/parseTreeCleaner.ts +35 -0
- package/src/analyzer/parseTreeUtils.ts +2165 -0
- package/src/analyzer/parseTreeWalker.ts +663 -0
- package/src/analyzer/patternMatching.ts +1356 -0
- package/src/analyzer/program.ts +2778 -0
- package/src/analyzer/properties.ts +534 -0
- package/src/analyzer/protocols.ts +660 -0
- package/src/analyzer/pyTypedUtils.ts +52 -0
- package/src/analyzer/pythonPathUtils.ts +201 -0
- package/src/analyzer/scope.ts +202 -0
- package/src/analyzer/scopeUtils.ts +81 -0
- package/src/analyzer/service.ts +1679 -0
- package/src/analyzer/sourceFile.ts +1401 -0
- package/src/analyzer/sourceMapper.ts +717 -0
- package/src/analyzer/staticExpressions.ts +308 -0
- package/src/analyzer/symbol.ts +249 -0
- package/src/analyzer/symbolNameUtils.ts +50 -0
- package/src/analyzer/symbolUtils.ts +49 -0
- package/src/analyzer/testWalker.ts +101 -0
- package/src/analyzer/tracePrinter.ts +264 -0
- package/src/analyzer/typeCache.ts +181 -0
- package/src/analyzer/typeDocStringUtils.ts +371 -0
- package/src/analyzer/typeEvaluator.ts +23395 -0
- package/src/analyzer/typeEvaluatorTypes.ts +452 -0
- package/src/analyzer/typeEvaluatorWithTracker.ts +161 -0
- package/src/analyzer/typeGuards.ts +1828 -0
- package/src/analyzer/typePrinter.ts +807 -0
- package/src/analyzer/typeStubWriter.ts +727 -0
- package/src/analyzer/typeUtils.ts +3126 -0
- package/src/analyzer/typeVarContext.ts +330 -0
- package/src/analyzer/typedDicts.ts +950 -0
- package/src/analyzer/types.ts +2857 -0
- package/src/backgroundAnalysis.ts +49 -0
- package/src/backgroundAnalysisBase.ts +606 -0
- package/src/backgroundThreadBase.ts +143 -0
- package/src/commands/commandController.ts +62 -0
- package/src/commands/commandResult.ts +21 -0
- package/src/commands/commands.ts +16 -0
- package/src/commands/createTypeStub.ts +56 -0
- package/src/commands/quickActionCommand.ts +40 -0
- package/src/commands/restartServer.ts +20 -0
- package/src/common/cancellationUtils.ts +71 -0
- package/src/common/chokidarFileWatcherProvider.ts +74 -0
- package/src/common/collectionUtils.ts +379 -0
- package/src/common/commandLineOptions.ts +132 -0
- package/src/common/configOptions.ts +1291 -0
- package/src/common/console.ts +201 -0
- package/src/common/core.ts +152 -0
- package/src/common/crypto.ts +60 -0
- package/src/common/debug.ts +144 -0
- package/src/common/deferred.ts +78 -0
- package/src/common/diagnostic.ts +191 -0
- package/src/common/diagnosticRules.ts +80 -0
- package/src/common/diagnosticSink.ts +150 -0
- package/src/common/editAction.ts +46 -0
- package/src/common/extensibility.ts +35 -0
- package/src/common/extensions.ts +21 -0
- package/src/common/fileBasedCancellationUtils.ts +274 -0
- package/src/common/fileSystem.ts +152 -0
- package/src/common/fullAccessHost.ts +203 -0
- package/src/common/host.ts +49 -0
- package/src/common/logTracker.ts +157 -0
- package/src/common/lspUtils.ts +18 -0
- package/src/common/memUtils.ts +36 -0
- package/src/common/pathConsts.ts +16 -0
- package/src/common/pathUtils.ts +987 -0
- package/src/common/positionUtils.ts +78 -0
- package/src/common/progressReporter.ts +53 -0
- package/src/common/pythonVersion.ts +74 -0
- package/src/common/realFileSystem.ts +433 -0
- package/src/common/stringUtils.ts +161 -0
- package/src/common/textEditUtils.ts +31 -0
- package/src/common/textRange.ts +225 -0
- package/src/common/textRangeCollection.ts +122 -0
- package/src/common/timing.ts +105 -0
- package/src/common/uriParser.ts +26 -0
- package/src/common/workspaceEditUtils.ts +100 -0
- package/src/languageServerBase.ts +1556 -0
- package/src/languageService/analyzerServiceExecutor.ts +144 -0
- package/src/languageService/autoImporter.ts +926 -0
- package/src/languageService/callHierarchyProvider.ts +476 -0
- package/src/languageService/codeActionProvider.ts +85 -0
- package/src/languageService/completionProvider.ts +3103 -0
- package/src/languageService/definitionProvider.ts +235 -0
- package/src/languageService/documentHighlightProvider.ts +61 -0
- package/src/languageService/documentSymbolCollector.ts +466 -0
- package/src/languageService/documentSymbolProvider.ts +466 -0
- package/src/languageService/hoverProvider.ts +499 -0
- package/src/languageService/importAdder.ts +437 -0
- package/src/languageService/importSorter.ts +196 -0
- package/src/languageService/indentationUtils.ts +813 -0
- package/src/languageService/quickActions.ts +113 -0
- package/src/languageService/referencesProvider.ts +316 -0
- package/src/languageService/renameModuleProvider.ts +1400 -0
- package/src/languageService/signatureHelpProvider.ts +227 -0
- package/src/languageService/tooltipUtils.ts +147 -0
- package/src/localization/localize.ts +1272 -0
- package/src/localization/package.nls.de.json +3 -0
- package/src/localization/package.nls.en-us.json +636 -0
- package/src/localization/package.nls.es.json +3 -0
- package/src/localization/package.nls.fr.json +3 -0
- package/src/localization/package.nls.ja.json +3 -0
- package/src/localization/package.nls.ru.json +3 -0
- package/src/localization/package.nls.zh-cn.json +3 -0
- package/src/localization/package.nls.zh-tw.json +3 -0
- package/src/nodeMain.ts +21 -0
- package/src/nodeServer.ts +30 -0
- package/src/parser/characterStream.ts +145 -0
- package/src/parser/characters.ts +285 -0
- package/src/parser/parseNodes.ts +2338 -0
- package/src/parser/parser.ts +4859 -0
- package/src/parser/stringTokenUtils.ts +564 -0
- package/src/parser/tokenizer.ts +1379 -0
- package/src/parser/tokenizerTypes.ts +420 -0
- package/src/parser/unicode.ts +2917 -0
- package/src/pyright.ts +824 -0
- package/src/pyrightFileSystem.ts +237 -0
- package/src/readonlyAugmentedFileSystem.ts +204 -0
- package/src/server.ts +298 -0
- package/src/tests/chainedSourceFiles.test.ts +183 -0
- package/src/tests/checker.test.ts +445 -0
- package/src/tests/collectionUtils.test.ts +178 -0
- package/src/tests/common.test.ts +117 -0
- package/src/tests/config.test.ts +291 -0
- package/src/tests/debug.test.ts +120 -0
- package/src/tests/deferred.test.ts +54 -0
- package/src/tests/diagnosticOverrides.test.ts +104 -0
- package/src/tests/docStringConversion.test.ts +823 -0
- package/src/tests/docStringUtils.test.ts +57 -0
- package/src/tests/documentSymbolCollector.test.ts +735 -0
- package/src/tests/filesystem.test.ts +215 -0
- package/src/tests/fourSlashParser.test.ts +330 -0
- package/src/tests/fourSlashRunner.test.ts +36 -0
- package/src/tests/fourslash/completions.autoimport.Lib.Found.Type.fourslash.ts +33 -0
- package/src/tests/fourslash/completions.autoimport.Lib.Found.duplication.fourslash.ts +47 -0
- package/src/tests/fourslash/completions.autoimport.Lib.NotFound.fourslash.ts +14 -0
- package/src/tests/fourslash/completions.autoimport.disabled.fourslash.ts +25 -0
- package/src/tests/fourslash/completions.autoimport.duplicates.fourslash.ts +36 -0
- package/src/tests/fourslash/completions.autoimport.fourslash.ts +29 -0
- package/src/tests/fourslash/completions.autoimport.fromImport.fourslash.ts +130 -0
- package/src/tests/fourslash/completions.autoimport.plainText.fourslash.ts +29 -0
- package/src/tests/fourslash/completions.autoimport.shadow.fourslash.ts +48 -0
- package/src/tests/fourslash/completions.autoimport.submodule.fourslash.ts +31 -0
- package/src/tests/fourslash/completions.autoimport.topLevel.fourslash.ts +57 -0
- package/src/tests/fourslash/completions.builtinDocstrings.fourslash.ts +117 -0
- package/src/tests/fourslash/completions.builtinOverride.fourslash.ts +22 -0
- package/src/tests/fourslash/completions.call.stringLiteral.fourslash.ts +55 -0
- package/src/tests/fourslash/completions.call.typedDict.fourslash.ts +247 -0
- package/src/tests/fourslash/completions.call.typedDict.list.fourslash.ts +163 -0
- package/src/tests/fourslash/completions.call.typedDict.states.fourslash.ts +135 -0
- package/src/tests/fourslash/completions.classVariable.fourslash.ts +37 -0
- package/src/tests/fourslash/completions.comment.fourslash.ts +28 -0
- package/src/tests/fourslash/completions.declNames.class.fourslash.ts +35 -0
- package/src/tests/fourslash/completions.declNames.exception.fourslash.ts +18 -0
- package/src/tests/fourslash/completions.declNames.for.fourslash.ts +30 -0
- package/src/tests/fourslash/completions.declNames.importAlias.fourslash.ts +15 -0
- package/src/tests/fourslash/completions.declNames.lambda.fourslash.ts +45 -0
- package/src/tests/fourslash/completions.declNames.method.fourslash.ts +71 -0
- package/src/tests/fourslash/completions.declNames.overload.fourslash.ts +156 -0
- package/src/tests/fourslash/completions.declNames.topLevelOverload.fourslash.ts +141 -0
- package/src/tests/fourslash/completions.dictionary.keys.complex.fourslash.ts +76 -0
- package/src/tests/fourslash/completions.dictionary.keys.expression.fourslash.ts +63 -0
- package/src/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.ts +161 -0
- package/src/tests/fourslash/completions.dictionary.keys.simple.fourslash.ts +151 -0
- package/src/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.ts +116 -0
- package/src/tests/fourslash/completions.dictionary.keys.symbols.fourslash.ts +53 -0
- package/src/tests/fourslash/completions.enums.members.fourslash.ts +44 -0
- package/src/tests/fourslash/completions.excluded.fourslash.ts +12 -0
- package/src/tests/fourslash/completions.fourslash.ts +51 -0
- package/src/tests/fourslash/completions.fstring.fourslash.ts +33 -0
- package/src/tests/fourslash/completions.fstring.stringLiteral.fourslash.ts +96 -0
- package/src/tests/fourslash/completions.fuzzyMatching.fourslash.ts +30 -0
- package/src/tests/fourslash/completions.importDunderNames.fourslash.ts +31 -0
- package/src/tests/fourslash/completions.importSubmodule.fourslash.ts +26 -0
- package/src/tests/fourslash/completions.importsDuplicates.fourslash.ts +23 -0
- package/src/tests/fourslash/completions.inList.fourslash.ts +33 -0
- package/src/tests/fourslash/completions.included.fourslash.ts +12 -0
- package/src/tests/fourslash/completions.indexer.keys.getitem.fourslash.ts +57 -0
- package/src/tests/fourslash/completions.inherited.function.docFromStub.fourslash.ts +28 -0
- package/src/tests/fourslash/completions.inherited.overload.docFromScrWithStub.fourslash.ts +52 -0
- package/src/tests/fourslash/completions.inherited.overload.docFromStub.fourslash.ts +53 -0
- package/src/tests/fourslash/completions.inherited.property.docFromSrc.fourslash.ts +104 -0
- package/src/tests/fourslash/completions.inherited.property.docFromStub.fourslash.ts +108 -0
- package/src/tests/fourslash/completions.keywords.pythonVersion.fourslash.ts +72 -0
- package/src/tests/fourslash/completions.libCodeAndStub.fourslash.ts +79 -0
- package/src/tests/fourslash/completions.libCodeNoStub.fourslash.ts +69 -0
- package/src/tests/fourslash/completions.libStub.fourslash.ts +69 -0
- package/src/tests/fourslash/completions.literals.fourslash.ts +33 -0
- package/src/tests/fourslash/completions.localCode.fourslash.ts +74 -0
- package/src/tests/fourslash/completions.moduleContext.UnknownMemberOnInstance.fourslash.ts +17 -0
- package/src/tests/fourslash/completions.moduleContext.UnknownStaticFunctionOnClass.fourslash.ts +57 -0
- package/src/tests/fourslash/completions.moduleContext.libCodeNoStub.fourslash.ts +30 -0
- package/src/tests/fourslash/completions.overloads.fourslash.ts +40 -0
- package/src/tests/fourslash/completions.override.default.fourslash.ts +47 -0
- package/src/tests/fourslash/completions.override.default.importStub.ts +50 -0
- package/src/tests/fourslash/completions.override.default.imported.fourslash.ts +61 -0
- package/src/tests/fourslash/completions.override.default.stub.fourslash.ts +47 -0
- package/src/tests/fourslash/completions.override.fourslash.ts +47 -0
- package/src/tests/fourslash/completions.override.property.fourslash.ts +31 -0
- package/src/tests/fourslash/completions.override.property.stub.fourslash.ts +31 -0
- package/src/tests/fourslash/completions.override.staticAndClassmethod.fourslash.ts +64 -0
- package/src/tests/fourslash/completions.override.stub.fourslash.ts +47 -0
- package/src/tests/fourslash/completions.override2.fourslash.ts +71 -0
- package/src/tests/fourslash/completions.parameters.fourslash.ts +23 -0
- package/src/tests/fourslash/completions.params.fourslash.ts +24 -0
- package/src/tests/fourslash/completions.parentFolder.fourslash.ts +17 -0
- package/src/tests/fourslash/completions.parentFolders.fourslash.ts +77 -0
- package/src/tests/fourslash/completions.plainText.fourslash.ts +34 -0
- package/src/tests/fourslash/completions.private.fourslash.ts +64 -0
- package/src/tests/fourslash/completions.property.fourslash.ts +28 -0
- package/src/tests/fourslash/completions.propertyDocStrings.fourslash.ts +64 -0
- package/src/tests/fourslash/completions.self.fourslash.ts +43 -0
- package/src/tests/fourslash/completions.stringLiteral.escape.fourslash.ts +71 -0
- package/src/tests/fourslash/completions.stringLiteral.fourslash.ts +79 -0
- package/src/tests/fourslash/completions.typeAlias.fourslash.ts +29 -0
- package/src/tests/fourslash/completions.typeshed.fourslash.ts +9 -0
- package/src/tests/fourslash/completions.vardecls.fourslash.ts +40 -0
- package/src/tests/fourslash/completions.variableDocStrings.fourslash.ts +69 -0
- package/src/tests/fourslash/completions.wildcardimports.fourslash.ts +116 -0
- package/src/tests/fourslash/completions.with.fourslash.ts +26 -0
- package/src/tests/fourslash/diagnostics.missingModuleSource.fourslash.ts +69 -0
- package/src/tests/fourslash/findDefinitions.builtinClass.fourslash.ts +29 -0
- package/src/tests/fourslash/findDefinitions.classes.fourslash.ts +101 -0
- package/src/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.ts +29 -0
- package/src/tests/fourslash/findDefinitions.definitionFilter.preferSource.onlyStubs.ts +24 -0
- package/src/tests/fourslash/findDefinitions.definitionFilter.preferStub.fourslash.ts +29 -0
- package/src/tests/fourslash/findDefinitions.definitionFilter.preferStub.onlySource.fourslash.ts +25 -0
- package/src/tests/fourslash/findDefinitions.fields.fourslash.ts +131 -0
- package/src/tests/fourslash/findDefinitions.functions.fourslash.ts +87 -0
- package/src/tests/fourslash/findDefinitions.methods.fourslash.ts +162 -0
- package/src/tests/fourslash/findDefinitions.modules.fourslash.ts +50 -0
- package/src/tests/fourslash/findDefinitions.namespaceImport.fourslash.ts +40 -0
- package/src/tests/fourslash/findDefinitions.overloads.fourslash.ts +223 -0
- package/src/tests/fourslash/findDefinitions.parameters.fourslash.ts +162 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.function.fourslash.ts +26 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.innerClass.fourslash.ts +32 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.innerClassMethod.fourslash.ts +33 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.outerClass.fourslash.ts +28 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.outerClassMethod.fourslash.ts +29 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadOnly.fourslash.ts +31 -0
- package/src/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadWrite.fourslash.ts +36 -0
- package/src/tests/fourslash/findDefinitions.sourceOnly.class.fourslash.ts +29 -0
- package/src/tests/fourslash/findDefinitions.sourceOnly.function1.fourslash.ts +28 -0
- package/src/tests/fourslash/findDefinitions.sourceOnly.function2.fourslash.ts +28 -0
- package/src/tests/fourslash/findDefinitions.sourceOnly.relativeImport1.fourslash.ts +22 -0
- package/src/tests/fourslash/findDefinitions.sourceOnly.relativeImport2.fourslash.ts +22 -0
- package/src/tests/fourslash/findDefinitions.stubOnly.fourslash.ts +61 -0
- package/src/tests/fourslash/findDefinitions.stubPackages.fourslash.ts +71 -0
- package/src/tests/fourslash/findDefinitions.typedDict.keys.fourslash.ts +99 -0
- package/src/tests/fourslash/findDefinitions.variables.fourslash.ts +88 -0
- package/src/tests/fourslash/findDefinitions.wildcardimports.fourslash.ts +117 -0
- package/src/tests/fourslash/findTypeDefinitions.builtinClass.fourslash.ts +26 -0
- package/src/tests/fourslash/findTypeDefinitions.classes.fourslash.ts +72 -0
- package/src/tests/fourslash/findTypeDefinitions.unions.fourslash.ts +26 -0
- package/src/tests/fourslash/findallreferences.classPropertyReadWrite.ts +39 -0
- package/src/tests/fourslash/findallreferences.fourslash.ts +34 -0
- package/src/tests/fourslash/findallreferences.importalias.fourslash.ts +34 -0
- package/src/tests/fourslash/findallreferences.invokedFromLibrary.fourslash.ts +52 -0
- package/src/tests/fourslash/findallreferences.module.nested.fourslash.ts +67 -0
- package/src/tests/fourslash/findallreferences.modules.duplicated.fourslash.ts +59 -0
- package/src/tests/fourslash/findallreferences.modules.fourslash.ts +46 -0
- package/src/tests/fourslash/findallreferences.modules.shadow.fourslash.ts +95 -0
- package/src/tests/fourslash/findallreferences.openFiles.fourslash.ts +37 -0
- package/src/tests/fourslash/findallreferences.parameter.fourslash.ts +24 -0
- package/src/tests/fourslash/findallreferences.sourceAndStub.class.fourslash.ts +33 -0
- package/src/tests/fourslash/findallreferences.sourceAndStub.classMethod.fourslash.ts +37 -0
- package/src/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadOnly.fourslash.ts +40 -0
- package/src/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadWrite.fourslash.skip.ts +48 -0
- package/src/tests/fourslash/findallreferences.sourceAndStub.function.fourslash.ts +35 -0
- package/src/tests/fourslash/findallreferences.variable.fourslash.ts +24 -0
- package/src/tests/fourslash/fourslash.ts +411 -0
- package/src/tests/fourslash/highlightreferences.attributes.fourslash.ts +31 -0
- package/src/tests/fourslash/hover.builtinDocstrings.fourslash.ts +64 -0
- package/src/tests/fourslash/hover.classNoInit.fourslash.ts +14 -0
- package/src/tests/fourslash/hover.docFromScr.stringFormat.fourslash.ts +52 -0
- package/src/tests/fourslash/hover.docFromSrc.fourslash.ts +83 -0
- package/src/tests/fourslash/hover.docFromSrc.pkg-vs-module1.fourslash.ts +26 -0
- package/src/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.ts +26 -0
- package/src/tests/fourslash/hover.docFromSrc.relativeImport1.fourslash.ts +23 -0
- package/src/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.ts +22 -0
- package/src/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.ts +46 -0
- package/src/tests/fourslash/hover.docFromSrc.stubs-package.fourslash.ts +29 -0
- package/src/tests/fourslash/hover.docFromSrc.typeshed.fourslash.ts +20 -0
- package/src/tests/fourslash/hover.docstring.links.fourslash.ts +12 -0
- package/src/tests/fourslash/hover.docstring.overloads.fourslash.ts +41 -0
- package/src/tests/fourslash/hover.docstring.split.fourslash.ts +24 -0
- package/src/tests/fourslash/hover.fourslash.ts +20 -0
- package/src/tests/fourslash/hover.import.django.view.fourslash.ts +27 -0
- package/src/tests/fourslash/hover.import.fourslash.ts +11 -0
- package/src/tests/fourslash/hover.inherited.docFromSrc.fourslash.ts +63 -0
- package/src/tests/fourslash/hover.inherited.docFromSrcWithStub.fourslash.ts +54 -0
- package/src/tests/fourslash/hover.inherited.docFromStub.fourslash.ts +42 -0
- package/src/tests/fourslash/hover.inherited.overload.docFromSrcWithStub.fourslash.ts +46 -0
- package/src/tests/fourslash/hover.inherited.overload.docFromStub.fourslash.ts +47 -0
- package/src/tests/fourslash/hover.inherited.property.docFromSrcWithStub.fourslash.ts +87 -0
- package/src/tests/fourslash/hover.inherited.property.docFromStub.fourslash.ts +91 -0
- package/src/tests/fourslash/hover.init.fourslash.ts +39 -0
- package/src/tests/fourslash/hover.libCodeAndStub.fourslash.ts +52 -0
- package/src/tests/fourslash/hover.libCodeNoStub.fourslash.ts +41 -0
- package/src/tests/fourslash/hover.libStub.fourslash.ts +41 -0
- package/src/tests/fourslash/hover.optionalAliasParameter.fourslash.ts +14 -0
- package/src/tests/fourslash/hover.plainText.fourslash.ts +21 -0
- package/src/tests/fourslash/hover.typedDict.key.fourslash.ts +51 -0
- package/src/tests/fourslash/hover.variable.docString.fourslash.ts +41 -0
- package/src/tests/fourslash/hover.wildcardimports.fourslash.ts +80 -0
- package/src/tests/fourslash/import.publicSymbols.fourslash.ts +65 -0
- package/src/tests/fourslash/import.pytyped.dunderAll.fourslash.ts +77 -0
- package/src/tests/fourslash/import.pytyped.privateSymbols.fourslash.ts +65 -0
- package/src/tests/fourslash/import.pytyped.typeCheckingBasic.fourslash.ts +38 -0
- package/src/tests/fourslash/import.pytyped.typeCheckingOff.fourslash.ts +38 -0
- package/src/tests/fourslash/import.wildcard.fourslash.ts +27 -0
- package/src/tests/fourslash/importnotresolved.fourslash.ts +13 -0
- package/src/tests/fourslash/missingModuleSource.disablingInStrictMode.fourslash.ts +20 -0
- package/src/tests/fourslash/missingModuleSource.fourslash.ts +14 -0
- package/src/tests/fourslash/missingTypeStub.codeAction.fourslash.ts +33 -0
- package/src/tests/fourslash/missingTypeStub.command.multipart.fourslash.ts +48 -0
- package/src/tests/fourslash/missingTypeStub.command.singlefile.fourslash.ts +38 -0
- package/src/tests/fourslash/missingTypeStub.command.singlepart.fourslash.ts +38 -0
- package/src/tests/fourslash/missingTypeStub.fourslash.ts +20 -0
- package/src/tests/fourslash/missingTypeStub.invokeCodeAction.fourslash.ts +36 -0
- package/src/tests/fourslash/noerrors.fourslash.ts +9 -0
- package/src/tests/fourslash/orderImports1.command.fourslash.ts +20 -0
- package/src/tests/fourslash/orderImports2.command.fourslash.ts +24 -0
- package/src/tests/fourslash/rename.externallyHidden.fourslash.ts +24 -0
- package/src/tests/fourslash/rename.externallyHidden.params.fourslash.ts +24 -0
- package/src/tests/fourslash/rename.fourslash.ts +29 -0
- package/src/tests/fourslash/rename.library.fourslash.ts +29 -0
- package/src/tests/fourslash/rename.library.sourceAndStub.fourslash.ts +33 -0
- package/src/tests/fourslash/rename.multipleDecl.fourslash.ts +21 -0
- package/src/tests/fourslash/rename.sourceAndStub.fourslash.ts +37 -0
- package/src/tests/fourslash/rename.string.excluded.fourslash.ts +43 -0
- package/src/tests/fourslash/rename.string.fourslash.ts +26 -0
- package/src/tests/fourslash/signature.builtinDocstrings.fourslash.ts +63 -0
- package/src/tests/fourslash/signature.complicated.fourslash.ts +100 -0
- package/src/tests/fourslash/signature.cornercases.fourslash.ts +23 -0
- package/src/tests/fourslash/signature.docstrings.fourslash.ts +43 -0
- package/src/tests/fourslash/signature.docstrings.overloaded.fourslash.ts +50 -0
- package/src/tests/fourslash/signature.docstrings.wildcardimports.fourslash.ts +122 -0
- package/src/tests/fourslash/signature.overload.fourslash.ts +64 -0
- package/src/tests/fourslash/signature.simple.fourslash.ts +104 -0
- package/src/tests/harness/fourslash/fourSlashParser.ts +441 -0
- package/src/tests/harness/fourslash/fourSlashTypes.ts +134 -0
- package/src/tests/harness/fourslash/runner.ts +99 -0
- package/src/tests/harness/fourslash/testLanguageService.ts +142 -0
- package/src/tests/harness/fourslash/testState.Consts.ts +29 -0
- package/src/tests/harness/fourslash/testState.ts +1993 -0
- package/src/tests/harness/testAccessHost.ts +23 -0
- package/src/tests/harness/testHost.ts +177 -0
- package/src/tests/harness/utils.ts +355 -0
- package/src/tests/harness/vfs/factory.ts +199 -0
- package/src/tests/harness/vfs/filesystem.ts +1893 -0
- package/src/tests/harness/vfs/pathValidation.ts +154 -0
- package/src/tests/importAdder.test.ts +1361 -0
- package/src/tests/importResolver.test.ts +534 -0
- package/src/tests/importStatementUtils.test.ts +526 -0
- package/src/tests/indentationUtils.ptvs.test.ts +388 -0
- package/src/tests/indentationUtils.reindent.test.ts +403 -0
- package/src/tests/indentationUtils.test.ts +455 -0
- package/src/tests/ipythonMode.test.ts +365 -0
- package/src/tests/localizer.test.ts +47 -0
- package/src/tests/parseTreeUtils.test.ts +281 -0
- package/src/tests/parser.test.ts +99 -0
- package/src/tests/pathUtils.test.ts +321 -0
- package/src/tests/pyrightFileSystem.test.ts +183 -0
- package/src/tests/renameModule.folder.test.ts +261 -0
- package/src/tests/renameModule.fromImports.test.ts +952 -0
- package/src/tests/renameModule.imports.test.ts +450 -0
- package/src/tests/renameModule.misc.test.ts +765 -0
- package/src/tests/renameModule.relativePath.test.ts +277 -0
- package/src/tests/renameModuleTestUtils.ts +210 -0
- package/src/tests/samples/abstractClass1.py +51 -0
- package/src/tests/samples/abstractClass2.py +25 -0
- package/src/tests/samples/abstractClass3.py +30 -0
- package/src/tests/samples/abstractClass4.py +30 -0
- package/src/tests/samples/abstractClass5.py +42 -0
- package/src/tests/samples/abstractClass6.py +25 -0
- package/src/tests/samples/abstractClass7.py +22 -0
- package/src/tests/samples/abstractClass8.py +27 -0
- package/src/tests/samples/annotated1.py +72 -0
- package/src/tests/samples/annotatedVar1.py +22 -0
- package/src/tests/samples/annotatedVar2.py +28 -0
- package/src/tests/samples/annotatedVar3.py +54 -0
- package/src/tests/samples/annotatedVar4.py +24 -0
- package/src/tests/samples/annotatedVar5.py +37 -0
- package/src/tests/samples/annotatedVar6.py +22 -0
- package/src/tests/samples/annotatedVar7.py +13 -0
- package/src/tests/samples/annotatedVar8.py +29 -0
- package/src/tests/samples/annotations1.py +98 -0
- package/src/tests/samples/annotations2.py +33 -0
- package/src/tests/samples/annotations3.py +43 -0
- package/src/tests/samples/annotations4.py +54 -0
- package/src/tests/samples/annotations5.py +9 -0
- package/src/tests/samples/annotations6.py +29 -0
- package/src/tests/samples/assert1.py +22 -0
- package/src/tests/samples/assertType1.py +46 -0
- package/src/tests/samples/assignment1.py +58 -0
- package/src/tests/samples/assignment10.py +14 -0
- package/src/tests/samples/assignment2.py +40 -0
- package/src/tests/samples/assignment3.py +46 -0
- package/src/tests/samples/assignment4.py +20 -0
- package/src/tests/samples/assignment5.py +16 -0
- package/src/tests/samples/assignment6.py +25 -0
- package/src/tests/samples/assignment7.py +13 -0
- package/src/tests/samples/assignment8.py +40 -0
- package/src/tests/samples/assignment9.py +25 -0
- package/src/tests/samples/assignmentExpr1.py +23 -0
- package/src/tests/samples/assignmentExpr2.py +49 -0
- package/src/tests/samples/assignmentExpr3.py +27 -0
- package/src/tests/samples/assignmentExpr4.py +49 -0
- package/src/tests/samples/assignmentExpr5.py +15 -0
- package/src/tests/samples/assignmentExpr6.py +10 -0
- package/src/tests/samples/assignmentExpr7.py +13 -0
- package/src/tests/samples/assignmentExpr8.py +11 -0
- package/src/tests/samples/assignmentExpr9.py +28 -0
- package/src/tests/samples/async1.py +49 -0
- package/src/tests/samples/augmentedAssignment1.py +62 -0
- package/src/tests/samples/augmentedAssignment2.py +23 -0
- package/src/tests/samples/augmentedAssignment3.py +8 -0
- package/src/tests/samples/await1.py +23 -0
- package/src/tests/samples/await2.py +25 -0
- package/src/tests/samples/badToken1.py +6 -0
- package/src/tests/samples/builtins1.py +2 -0
- package/src/tests/samples/call1.py +93 -0
- package/src/tests/samples/call2.py +118 -0
- package/src/tests/samples/call3.py +168 -0
- package/src/tests/samples/call4.py +13 -0
- package/src/tests/samples/call5.py +95 -0
- package/src/tests/samples/call6.py +35 -0
- package/src/tests/samples/call7.py +57 -0
- package/src/tests/samples/callSite1.py +6 -0
- package/src/tests/samples/callSite2.py +12 -0
- package/src/tests/samples/callable1.py +53 -0
- package/src/tests/samples/callable2.py +58 -0
- package/src/tests/samples/callable3.py +28 -0
- package/src/tests/samples/callable4.py +32 -0
- package/src/tests/samples/callable5.py +40 -0
- package/src/tests/samples/callable6.py +83 -0
- package/src/tests/samples/callbackProtocol1.py +119 -0
- package/src/tests/samples/callbackProtocol2.py +29 -0
- package/src/tests/samples/callbackProtocol3.py +23 -0
- package/src/tests/samples/callbackProtocol4.py +73 -0
- package/src/tests/samples/callbackProtocol5.py +66 -0
- package/src/tests/samples/callbackProtocol6.py +66 -0
- package/src/tests/samples/callbackProtocol7.py +16 -0
- package/src/tests/samples/callbackProtocol8.py +16 -0
- package/src/tests/samples/capturedVariable1.py +106 -0
- package/src/tests/samples/circular1.py +16 -0
- package/src/tests/samples/circular2.py +38 -0
- package/src/tests/samples/circularBaseClass.py +17 -0
- package/src/tests/samples/classGetItem1.py +30 -0
- package/src/tests/samples/classVar1.py +41 -0
- package/src/tests/samples/classVar2.py +29 -0
- package/src/tests/samples/classVar3.py +46 -0
- package/src/tests/samples/classVar4.py +36 -0
- package/src/tests/samples/classes1.py +50 -0
- package/src/tests/samples/classes3.py +48 -0
- package/src/tests/samples/classes4.py +15 -0
- package/src/tests/samples/classes5.py +260 -0
- package/src/tests/samples/classes6.py +16 -0
- package/src/tests/samples/classes7.py +18 -0
- package/src/tests/samples/classes8.py +47 -0
- package/src/tests/samples/codeFlow1.py +65 -0
- package/src/tests/samples/codeFlow2.py +26 -0
- package/src/tests/samples/codeFlow3.py +8 -0
- package/src/tests/samples/codeFlow4.py +133 -0
- package/src/tests/samples/codeFlow5.py +10 -0
- package/src/tests/samples/codeFlow6.py +35 -0
- package/src/tests/samples/codeFlow7.py +35 -0
- package/src/tests/samples/comparison1.py +77 -0
- package/src/tests/samples/comparison2.py +37 -0
- package/src/tests/samples/complex1.py +17 -0
- package/src/tests/samples/constant1.py +40 -0
- package/src/tests/samples/constants1.py +64 -0
- package/src/tests/samples/constructor1.py +30 -0
- package/src/tests/samples/constructor10.py +19 -0
- package/src/tests/samples/constructor11.py +32 -0
- package/src/tests/samples/constructor12.py +20 -0
- package/src/tests/samples/constructor13.py +15 -0
- package/src/tests/samples/constructor2.py +180 -0
- package/src/tests/samples/constructor3.py +18 -0
- package/src/tests/samples/constructor4.py +25 -0
- package/src/tests/samples/constructor5.py +25 -0
- package/src/tests/samples/constructor6.py +70 -0
- package/src/tests/samples/constructor7.py +11 -0
- package/src/tests/samples/constructor8.py +99 -0
- package/src/tests/samples/constructor9.py +19 -0
- package/src/tests/samples/coroutines1.py +60 -0
- package/src/tests/samples/coroutines2.py +20 -0
- package/src/tests/samples/coroutines3.py +37 -0
- package/src/tests/samples/dataclass1.py +44 -0
- package/src/tests/samples/dataclass10.py +45 -0
- package/src/tests/samples/dataclass11.py +53 -0
- package/src/tests/samples/dataclass12.py +32 -0
- package/src/tests/samples/dataclass13.py +42 -0
- package/src/tests/samples/dataclass14.py +38 -0
- package/src/tests/samples/dataclass15.py +58 -0
- package/src/tests/samples/dataclass16.py +21 -0
- package/src/tests/samples/dataclass17.py +46 -0
- package/src/tests/samples/dataclass18.py +57 -0
- package/src/tests/samples/dataclass19.py +44 -0
- package/src/tests/samples/dataclass2.py +30 -0
- package/src/tests/samples/dataclass20.py +71 -0
- package/src/tests/samples/dataclass21.py +13 -0
- package/src/tests/samples/dataclass3.py +18 -0
- package/src/tests/samples/dataclass4.py +64 -0
- package/src/tests/samples/dataclass5.py +81 -0
- package/src/tests/samples/dataclass6.py +29 -0
- package/src/tests/samples/dataclass7.py +93 -0
- package/src/tests/samples/dataclass8.py +22 -0
- package/src/tests/samples/dataclass9.py +24 -0
- package/src/tests/samples/dataclassPostInit1.py +61 -0
- package/src/tests/samples/dataclassTransform1.py +71 -0
- package/src/tests/samples/dataclassTransform2.py +78 -0
- package/src/tests/samples/dataclassTransform3.py +83 -0
- package/src/tests/samples/dataclassTransform4.py +87 -0
- package/src/tests/samples/decorator1.py +20 -0
- package/src/tests/samples/decorator2.py +31 -0
- package/src/tests/samples/decorator3.py +27 -0
- package/src/tests/samples/decorator4.py +37 -0
- package/src/tests/samples/decorator5.py +29 -0
- package/src/tests/samples/decorator6.py +34 -0
- package/src/tests/samples/defaultInitializer1.py +26 -0
- package/src/tests/samples/deprecated1.py +37 -0
- package/src/tests/samples/descriptor1.py +134 -0
- package/src/tests/samples/descriptor2.py +29 -0
- package/src/tests/samples/dictionary1.py +42 -0
- package/src/tests/samples/dictionary2.py +14 -0
- package/src/tests/samples/dictionary3.py +30 -0
- package/src/tests/samples/dictionary4.py +106 -0
- package/src/tests/samples/dunderAll1.py +32 -0
- package/src/tests/samples/dunderAll2.py +16 -0
- package/src/tests/samples/dunderAll3.pyi +16 -0
- package/src/tests/samples/duplicateDeclaration1.py +115 -0
- package/src/tests/samples/duplicateDeclaration2.py +45 -0
- package/src/tests/samples/duplicateImports1.py +13 -0
- package/src/tests/samples/ellipsis1.pyi +48 -0
- package/src/tests/samples/emptyContainers1.py +89 -0
- package/src/tests/samples/enums1.py +52 -0
- package/src/tests/samples/enums2.py +15 -0
- package/src/tests/samples/enums3.py +24 -0
- package/src/tests/samples/enums4.py +23 -0
- package/src/tests/samples/enums5.py +16 -0
- package/src/tests/samples/enums6.py +33 -0
- package/src/tests/samples/enums7.py +54 -0
- package/src/tests/samples/enums8.py +14 -0
- package/src/tests/samples/expressions1.py +54 -0
- package/src/tests/samples/expressions2.py +29 -0
- package/src/tests/samples/expressions3.py +26 -0
- package/src/tests/samples/expressions4.py +23 -0
- package/src/tests/samples/expressions5.py +70 -0
- package/src/tests/samples/expressions6.py +14 -0
- package/src/tests/samples/expressions7.py +40 -0
- package/src/tests/samples/expressions8.py +26 -0
- package/src/tests/samples/expressions9.py +14 -0
- package/src/tests/samples/final1.py +14 -0
- package/src/tests/samples/final2.py +86 -0
- package/src/tests/samples/final3.py +179 -0
- package/src/tests/samples/final4.pyi +21 -0
- package/src/tests/samples/final5.py +18 -0
- package/src/tests/samples/forLoop1.py +88 -0
- package/src/tests/samples/forLoop2.py +48 -0
- package/src/tests/samples/fstring1.py +66 -0
- package/src/tests/samples/fstring2.py +12 -0
- package/src/tests/samples/fstring3.py +35 -0
- package/src/tests/samples/fstring4.py +17 -0
- package/src/tests/samples/fstring5.py +17 -0
- package/src/tests/samples/fstring6.py +14 -0
- package/src/tests/samples/function1.py +12 -0
- package/src/tests/samples/function10.py +20 -0
- package/src/tests/samples/function11.py +36 -0
- package/src/tests/samples/function2.py +7 -0
- package/src/tests/samples/function3.py +82 -0
- package/src/tests/samples/function4.py +13 -0
- package/src/tests/samples/function6.py +24 -0
- package/src/tests/samples/function7.py +13 -0
- package/src/tests/samples/function8.py +38 -0
- package/src/tests/samples/function9.py +75 -0
- package/src/tests/samples/functionAnnotation1.py +61 -0
- package/src/tests/samples/functionAnnotation2.py +26 -0
- package/src/tests/samples/functionAnnotation3.py +37 -0
- package/src/tests/samples/functionAnnotation4.py +22 -0
- package/src/tests/samples/functionMember1.py +18 -0
- package/src/tests/samples/functionMember2.py +45 -0
- package/src/tests/samples/generators1.py +122 -0
- package/src/tests/samples/generators10.py +18 -0
- package/src/tests/samples/generators11.py +27 -0
- package/src/tests/samples/generators12.py +25 -0
- package/src/tests/samples/generators13.py +65 -0
- package/src/tests/samples/generators14.py +19 -0
- package/src/tests/samples/generators15.py +26 -0
- package/src/tests/samples/generators2.py +31 -0
- package/src/tests/samples/generators3.py +42 -0
- package/src/tests/samples/generators4.py +33 -0
- package/src/tests/samples/generators5.py +24 -0
- package/src/tests/samples/generators6.py +14 -0
- package/src/tests/samples/generators7.py +18 -0
- package/src/tests/samples/generators8.py +12 -0
- package/src/tests/samples/generators9.py +19 -0
- package/src/tests/samples/generic1.py +41 -0
- package/src/tests/samples/genericTypes1.py +12 -0
- package/src/tests/samples/genericTypes10.py +38 -0
- package/src/tests/samples/genericTypes11.py +26 -0
- package/src/tests/samples/genericTypes12.py +14 -0
- package/src/tests/samples/genericTypes13.py +27 -0
- package/src/tests/samples/genericTypes14.py +22 -0
- package/src/tests/samples/genericTypes15.py +13 -0
- package/src/tests/samples/genericTypes16.py +15 -0
- package/src/tests/samples/genericTypes17.py +24 -0
- package/src/tests/samples/genericTypes18.py +135 -0
- package/src/tests/samples/genericTypes19.py +32 -0
- package/src/tests/samples/genericTypes2.py +40 -0
- package/src/tests/samples/genericTypes20.py +44 -0
- package/src/tests/samples/genericTypes21.py +29 -0
- package/src/tests/samples/genericTypes22.py +23 -0
- package/src/tests/samples/genericTypes23.py +27 -0
- package/src/tests/samples/genericTypes24.py +32 -0
- package/src/tests/samples/genericTypes25.py +37 -0
- package/src/tests/samples/genericTypes26.py +31 -0
- package/src/tests/samples/genericTypes27.py +14 -0
- package/src/tests/samples/genericTypes28.py +51 -0
- package/src/tests/samples/genericTypes29.py +24 -0
- package/src/tests/samples/genericTypes3.py +13 -0
- package/src/tests/samples/genericTypes30.py +32 -0
- package/src/tests/samples/genericTypes31.py +30 -0
- package/src/tests/samples/genericTypes32.py +25 -0
- package/src/tests/samples/genericTypes33.py +46 -0
- package/src/tests/samples/genericTypes34.py +54 -0
- package/src/tests/samples/genericTypes35.py +45 -0
- package/src/tests/samples/genericTypes36.py +35 -0
- package/src/tests/samples/genericTypes37.py +26 -0
- package/src/tests/samples/genericTypes38.py +15 -0
- package/src/tests/samples/genericTypes39.py +82 -0
- package/src/tests/samples/genericTypes4.py +37 -0
- package/src/tests/samples/genericTypes40.py +38 -0
- package/src/tests/samples/genericTypes41.py +16 -0
- package/src/tests/samples/genericTypes42.py +32 -0
- package/src/tests/samples/genericTypes43.py +24 -0
- package/src/tests/samples/genericTypes44.py +33 -0
- package/src/tests/samples/genericTypes45.py +43 -0
- package/src/tests/samples/genericTypes46.py +66 -0
- package/src/tests/samples/genericTypes47.py +39 -0
- package/src/tests/samples/genericTypes48.py +18 -0
- package/src/tests/samples/genericTypes49.py +41 -0
- package/src/tests/samples/genericTypes5.py +42 -0
- package/src/tests/samples/genericTypes50.py +62 -0
- package/src/tests/samples/genericTypes51.py +55 -0
- package/src/tests/samples/genericTypes52.py +34 -0
- package/src/tests/samples/genericTypes53.py +42 -0
- package/src/tests/samples/genericTypes54.py +31 -0
- package/src/tests/samples/genericTypes55.py +61 -0
- package/src/tests/samples/genericTypes56.py +19 -0
- package/src/tests/samples/genericTypes57.py +30 -0
- package/src/tests/samples/genericTypes58.py +52 -0
- package/src/tests/samples/genericTypes59.py +71 -0
- package/src/tests/samples/genericTypes6.py +49 -0
- package/src/tests/samples/genericTypes60.py +27 -0
- package/src/tests/samples/genericTypes61.py +34 -0
- package/src/tests/samples/genericTypes62.py +26 -0
- package/src/tests/samples/genericTypes63.py +32 -0
- package/src/tests/samples/genericTypes64.py +16 -0
- package/src/tests/samples/genericTypes65.py +15 -0
- package/src/tests/samples/genericTypes66.py +30 -0
- package/src/tests/samples/genericTypes67.py +57 -0
- package/src/tests/samples/genericTypes68.py +14 -0
- package/src/tests/samples/genericTypes69.py +45 -0
- package/src/tests/samples/genericTypes7.py +24 -0
- package/src/tests/samples/genericTypes70.py +31 -0
- package/src/tests/samples/genericTypes71.py +72 -0
- package/src/tests/samples/genericTypes72.py +24 -0
- package/src/tests/samples/genericTypes73.py +14 -0
- package/src/tests/samples/genericTypes74.py +23 -0
- package/src/tests/samples/genericTypes75.py +45 -0
- package/src/tests/samples/genericTypes76.py +107 -0
- package/src/tests/samples/genericTypes77.py +26 -0
- package/src/tests/samples/genericTypes78.py +23 -0
- package/src/tests/samples/genericTypes79.py +37 -0
- package/src/tests/samples/genericTypes8.py +26 -0
- package/src/tests/samples/genericTypes80.py +10 -0
- package/src/tests/samples/genericTypes81.py +32 -0
- package/src/tests/samples/genericTypes82.py +19 -0
- package/src/tests/samples/genericTypes83.py +28 -0
- package/src/tests/samples/genericTypes84.py +11 -0
- package/src/tests/samples/genericTypes85.py +20 -0
- package/src/tests/samples/genericTypes86.py +15 -0
- package/src/tests/samples/genericTypes87.py +21 -0
- package/src/tests/samples/genericTypes88.py +25 -0
- package/src/tests/samples/genericTypes89.py +17 -0
- package/src/tests/samples/genericTypes9.py +109 -0
- package/src/tests/samples/genericTypes90.py +12 -0
- package/src/tests/samples/genericTypes91.py +20 -0
- package/src/tests/samples/import1.py +7 -0
- package/src/tests/samples/import10.py +11 -0
- package/src/tests/samples/import11.py +11 -0
- package/src/tests/samples/import12.py +5 -0
- package/src/tests/samples/import13.py +6 -0
- package/src/tests/samples/import14.py +10 -0
- package/src/tests/samples/import2.py +27 -0
- package/src/tests/samples/import3.py +8 -0
- package/src/tests/samples/import4.py +15 -0
- package/src/tests/samples/import5.py +6 -0
- package/src/tests/samples/import6.py +17 -0
- package/src/tests/samples/import7.py +14 -0
- package/src/tests/samples/import8.py +7 -0
- package/src/tests/samples/import9.py +7 -0
- package/src/tests/samples/inconsistentConstructor1.py +23 -0
- package/src/tests/samples/inconsistentSpaceTab1.py +9 -0
- package/src/tests/samples/inconsistentSpaceTab2.py +10 -0
- package/src/tests/samples/index1.py +97 -0
- package/src/tests/samples/inferredTypes1.py +25 -0
- package/src/tests/samples/initVar1.py +23 -0
- package/src/tests/samples/initsubclass1.py +46 -0
- package/src/tests/samples/initsubclass2.py +16 -0
- package/src/tests/samples/isinstance1.py +57 -0
- package/src/tests/samples/isinstance10.py +15 -0
- package/src/tests/samples/isinstance2.py +28 -0
- package/src/tests/samples/isinstance3.py +59 -0
- package/src/tests/samples/isinstance4.py +57 -0
- package/src/tests/samples/isinstance5.py +8 -0
- package/src/tests/samples/isinstance6.py +19 -0
- package/src/tests/samples/isinstance7.py +42 -0
- package/src/tests/samples/isinstance9.py +26 -0
- package/src/tests/samples/kwargsUnpack1.py +116 -0
- package/src/tests/samples/lambda1.py +77 -0
- package/src/tests/samples/lambda2.py +26 -0
- package/src/tests/samples/lambda3.py +34 -0
- package/src/tests/samples/lambda4.py +70 -0
- package/src/tests/samples/lambda5.py +23 -0
- package/src/tests/samples/lambda6.py +15 -0
- package/src/tests/samples/lines1.py +14 -0
- package/src/tests/samples/list1.py +90 -0
- package/src/tests/samples/listComprehension1.py +45 -0
- package/src/tests/samples/listComprehension2.py +17 -0
- package/src/tests/samples/listComprehension3.py +12 -0
- package/src/tests/samples/listComprehension4.py +15 -0
- package/src/tests/samples/listComprehension5.py +20 -0
- package/src/tests/samples/listComprehension6.py +14 -0
- package/src/tests/samples/listComprehension7.py +15 -0
- package/src/tests/samples/listComprehension8.py +15 -0
- package/src/tests/samples/literalString1.py +43 -0
- package/src/tests/samples/literals1.py +48 -0
- package/src/tests/samples/literals2.py +30 -0
- package/src/tests/samples/literals3.py +40 -0
- package/src/tests/samples/literals4.py +10 -0
- package/src/tests/samples/literals5.py +28 -0
- package/src/tests/samples/literals6.py +90 -0
- package/src/tests/samples/literals7.py +38 -0
- package/src/tests/samples/loops1.py +45 -0
- package/src/tests/samples/loops10.py +11 -0
- package/src/tests/samples/loops11.py +22 -0
- package/src/tests/samples/loops12.py +18 -0
- package/src/tests/samples/loops13.py +13 -0
- package/src/tests/samples/loops14.py +22 -0
- package/src/tests/samples/loops15.py +22 -0
- package/src/tests/samples/loops16.py +322 -0
- package/src/tests/samples/loops17.py +9 -0
- package/src/tests/samples/loops18.py +23 -0
- package/src/tests/samples/loops19.py +14 -0
- package/src/tests/samples/loops2.py +25 -0
- package/src/tests/samples/loops20.py +41 -0
- package/src/tests/samples/loops21.py +18 -0
- package/src/tests/samples/loops22.py +21 -0
- package/src/tests/samples/loops23.py +16 -0
- package/src/tests/samples/loops24.py +12 -0
- package/src/tests/samples/loops25.py +45 -0
- package/src/tests/samples/loops26.py +12 -0
- package/src/tests/samples/loops3.py +11 -0
- package/src/tests/samples/loops4.py +17 -0
- package/src/tests/samples/loops5.py +14 -0
- package/src/tests/samples/loops6.py +25 -0
- package/src/tests/samples/loops7.py +14 -0
- package/src/tests/samples/loops8.py +17 -0
- package/src/tests/samples/loops9.py +25 -0
- package/src/tests/samples/match1.py +190 -0
- package/src/tests/samples/match10.py +67 -0
- package/src/tests/samples/match2.py +340 -0
- package/src/tests/samples/match3.py +364 -0
- package/src/tests/samples/match4.py +100 -0
- package/src/tests/samples/match5.py +70 -0
- package/src/tests/samples/match6.py +64 -0
- package/src/tests/samples/match7.py +65 -0
- package/src/tests/samples/match8.py +19 -0
- package/src/tests/samples/match9.py +53 -0
- package/src/tests/samples/maxParseDepth1.py +499 -0
- package/src/tests/samples/maxParseDepth2.py +16 -0
- package/src/tests/samples/memberAccess1.py +70 -0
- package/src/tests/samples/memberAccess10.py +65 -0
- package/src/tests/samples/memberAccess11.py +37 -0
- package/src/tests/samples/memberAccess12.py +36 -0
- package/src/tests/samples/memberAccess13.py +17 -0
- package/src/tests/samples/memberAccess14.py +63 -0
- package/src/tests/samples/memberAccess15.py +20 -0
- package/src/tests/samples/memberAccess16.py +12 -0
- package/src/tests/samples/memberAccess17.py +31 -0
- package/src/tests/samples/memberAccess18.py +31 -0
- package/src/tests/samples/memberAccess2.py +45 -0
- package/src/tests/samples/memberAccess3.py +64 -0
- package/src/tests/samples/memberAccess4.py +91 -0
- package/src/tests/samples/memberAccess5.py +26 -0
- package/src/tests/samples/memberAccess6.py +52 -0
- package/src/tests/samples/memberAccess7.py +36 -0
- package/src/tests/samples/memberAccess8.py +75 -0
- package/src/tests/samples/memberAccess9.py +11 -0
- package/src/tests/samples/metaclass1.py +7 -0
- package/src/tests/samples/metaclass2.py +35 -0
- package/src/tests/samples/metaclass3.py +43 -0
- package/src/tests/samples/metaclass4.py +26 -0
- package/src/tests/samples/metaclass5.py +33 -0
- package/src/tests/samples/metaclass6.py +15 -0
- package/src/tests/samples/metaclass7.py +38 -0
- package/src/tests/samples/metaclass8.py +20 -0
- package/src/tests/samples/metaclass9.py +77 -0
- package/src/tests/samples/methodOverride1.py +507 -0
- package/src/tests/samples/methodOverride2.py +74 -0
- package/src/tests/samples/methodOverride3.py +111 -0
- package/src/tests/samples/methodOverride4.py +36 -0
- package/src/tests/samples/missingSuper1.py +73 -0
- package/src/tests/samples/module1.py +13 -0
- package/src/tests/samples/module2.py +7 -0
- package/src/tests/samples/mro1.py +16 -0
- package/src/tests/samples/mro2.py +45 -0
- package/src/tests/samples/mro3.py +30 -0
- package/src/tests/samples/mro4.py +30 -0
- package/src/tests/samples/nameBindings1.py +48 -0
- package/src/tests/samples/nameBindings2.py +9 -0
- package/src/tests/samples/nameBindings3.py +36 -0
- package/src/tests/samples/nameBindings4.py +10 -0
- package/src/tests/samples/nameBindings5.py +53 -0
- package/src/tests/samples/namedTuples1.py +103 -0
- package/src/tests/samples/namedTuples2.py +56 -0
- package/src/tests/samples/namedTuples3.py +15 -0
- package/src/tests/samples/namedTuples4.py +24 -0
- package/src/tests/samples/namedTuples5.py +15 -0
- package/src/tests/samples/namedTuples6.py +31 -0
- package/src/tests/samples/namedTuples7.py +27 -0
- package/src/tests/samples/never1.py +12 -0
- package/src/tests/samples/never2.py +43 -0
- package/src/tests/samples/newType1.py +34 -0
- package/src/tests/samples/newType2.py +25 -0
- package/src/tests/samples/newType3.py +34 -0
- package/src/tests/samples/newType4.py +8 -0
- package/src/tests/samples/none1.py +29 -0
- package/src/tests/samples/none2.py +22 -0
- package/src/tests/samples/noreturn1.py +78 -0
- package/src/tests/samples/noreturn2.py +37 -0
- package/src/tests/samples/noreturn3.py +16 -0
- package/src/tests/samples/noreturn4.py +29 -0
- package/src/tests/samples/operators1.py +101 -0
- package/src/tests/samples/operators2.py +30 -0
- package/src/tests/samples/operators3.py +8 -0
- package/src/tests/samples/operators4.py +22 -0
- package/src/tests/samples/operators5.py +5 -0
- package/src/tests/samples/operators6.py +10 -0
- package/src/tests/samples/operators7.py +24 -0
- package/src/tests/samples/operators8.py +125 -0
- package/src/tests/samples/optional1.py +77 -0
- package/src/tests/samples/optional2.py +23 -0
- package/src/tests/samples/overload1.py +50 -0
- package/src/tests/samples/overload10.py +48 -0
- package/src/tests/samples/overload2.py +37 -0
- package/src/tests/samples/overload3.py +29 -0
- package/src/tests/samples/overload4.py +46 -0
- package/src/tests/samples/overload5.py +333 -0
- package/src/tests/samples/overload6.py +64 -0
- package/src/tests/samples/overload7.py +376 -0
- package/src/tests/samples/overload8.py +89 -0
- package/src/tests/samples/overload9.py +19 -0
- package/src/tests/samples/package1/__init__.py +3 -0
- package/src/tests/samples/package1/psyche/pysche.py +4 -0
- package/src/tests/samples/package1/psyche.py +4 -0
- package/src/tests/samples/package1/sub/__init__.py +5 -0
- package/src/tests/samples/package1/sub.py +4 -0
- package/src/tests/samples/package1/sub.pyi +2 -0
- package/src/tests/samples/paramInference1.py +27 -0
- package/src/tests/samples/paramNames1.py +39 -0
- package/src/tests/samples/paramSpec1.py +64 -0
- package/src/tests/samples/paramSpec10.py +57 -0
- package/src/tests/samples/paramSpec11.py +36 -0
- package/src/tests/samples/paramSpec12.py +88 -0
- package/src/tests/samples/paramSpec13.py +112 -0
- package/src/tests/samples/paramSpec14.py +30 -0
- package/src/tests/samples/paramSpec15.py +28 -0
- package/src/tests/samples/paramSpec16.py +28 -0
- package/src/tests/samples/paramSpec17.py +34 -0
- package/src/tests/samples/paramSpec18.py +43 -0
- package/src/tests/samples/paramSpec19.py +93 -0
- package/src/tests/samples/paramSpec2.py +29 -0
- package/src/tests/samples/paramSpec20.py +87 -0
- package/src/tests/samples/paramSpec21.py +58 -0
- package/src/tests/samples/paramSpec22.py +26 -0
- package/src/tests/samples/paramSpec23.py +21 -0
- package/src/tests/samples/paramSpec24.py +67 -0
- package/src/tests/samples/paramSpec25.py +36 -0
- package/src/tests/samples/paramSpec26.py +25 -0
- package/src/tests/samples/paramSpec27.py +57 -0
- package/src/tests/samples/paramSpec28.py +39 -0
- package/src/tests/samples/paramSpec29.py +37 -0
- package/src/tests/samples/paramSpec3.py +71 -0
- package/src/tests/samples/paramSpec30.py +49 -0
- package/src/tests/samples/paramSpec31.py +16 -0
- package/src/tests/samples/paramSpec32.py +57 -0
- package/src/tests/samples/paramSpec33.py +29 -0
- package/src/tests/samples/paramSpec34.py +29 -0
- package/src/tests/samples/paramSpec35.py +24 -0
- package/src/tests/samples/paramSpec36.py +43 -0
- package/src/tests/samples/paramSpec37.py +25 -0
- package/src/tests/samples/paramSpec4.py +109 -0
- package/src/tests/samples/paramSpec5.py +29 -0
- package/src/tests/samples/paramSpec6.py +17 -0
- package/src/tests/samples/paramSpec7.py +22 -0
- package/src/tests/samples/paramSpec8.py +45 -0
- package/src/tests/samples/paramSpec9.py +57 -0
- package/src/tests/samples/paramType1.py +71 -0
- package/src/tests/samples/parameters1.py +16 -0
- package/src/tests/samples/partial1.py +163 -0
- package/src/tests/samples/partial2.py +31 -0
- package/src/tests/samples/private1.py +55 -0
- package/src/tests/samples/private2.py +11 -0
- package/src/tests/samples/project1/pyrightconfig.json +5 -0
- package/src/tests/samples/project1/sample1.py +0 -0
- package/src/tests/samples/project1/subfolder1/sample2.py +0 -0
- package/src/tests/samples/project1/subfolder1/subfolder1-1/sample3.py +0 -0
- package/src/tests/samples/project2/pyrightconfig.json +3 -0
- package/src/tests/samples/project3/pyrightconfig.json +7 -0
- package/src/tests/samples/project4/presentfile.py +0 -0
- package/src/tests/samples/project4/pyrightconfig.json +11 -0
- package/src/tests/samples/project4/subfolder/presentfile2.py +0 -0
- package/src/tests/samples/project4/subfolder/presentfile3.py +0 -0
- package/src/tests/samples/project5/pyrightconfig.json +4 -0
- package/src/tests/samples/project6/app1.py +0 -0
- package/src/tests/samples/project6/app2.py +0 -0
- package/src/tests/samples/project6/projectA/foo/__init__.py +0 -0
- package/src/tests/samples/project6/projectA/foo/bar/__init__.py +0 -0
- package/src/tests/samples/project6/projectB/foo/__init__.py +0 -0
- package/src/tests/samples/project6/projectB/foo/baz/__init__.py +0 -0
- package/src/tests/samples/project_src/src/module1.py +0 -0
- package/src/tests/samples/project_src_is_pkg/src/__init__.py +0 -0
- package/src/tests/samples/project_src_is_pkg/src/module1.py +0 -0
- package/src/tests/samples/project_src_with_config_extra_paths/pyrightconfig.json +3 -0
- package/src/tests/samples/project_src_with_config_extra_paths/src/module1.py +0 -0
- package/src/tests/samples/project_src_with_config_no_extra_paths/pyrightconfig.json +2 -0
- package/src/tests/samples/project_src_with_config_no_extra_paths/src/module1.py +0 -0
- package/src/tests/samples/project_src_with_extra_paths/src/_vendored/vendored1.py +1 -0
- package/src/tests/samples/project_src_with_extra_paths/src/module1.py +2 -0
- package/src/tests/samples/project_with_pyproject_toml/pyproject.toml +7 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/myvenv/Lib/site-packages/library1.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/myvenv/pyvenv.cfg +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/pyrightconfig.json +2 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/sample1.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/subfolder1/sample2.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_exclude/subfolder1/subfolder1-1/sample3.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/excluded/excluded1.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/myvenv/Lib/site-packages/library1.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/myvenv/pyvenv.cfg +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/pyrightconfig.json +3 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/sample1.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/subfolder1/sample2.py +0 -0
- package/src/tests/samples/project_with_venv_auto_detect_include/subfolder1/subfolder1-1/sample3.py +0 -0
- package/src/tests/samples/properties1.py +64 -0
- package/src/tests/samples/properties10.py +19 -0
- package/src/tests/samples/properties11.py +45 -0
- package/src/tests/samples/properties12.py +23 -0
- package/src/tests/samples/properties13.py +15 -0
- package/src/tests/samples/properties2.py +34 -0
- package/src/tests/samples/properties3.py +93 -0
- package/src/tests/samples/properties4.py +17 -0
- package/src/tests/samples/properties5.py +29 -0
- package/src/tests/samples/properties6.py +35 -0
- package/src/tests/samples/properties7.py +30 -0
- package/src/tests/samples/properties8.py +26 -0
- package/src/tests/samples/properties9.py +24 -0
- package/src/tests/samples/protocol1.py +132 -0
- package/src/tests/samples/protocol10.py +36 -0
- package/src/tests/samples/protocol11.py +32 -0
- package/src/tests/samples/protocol12.py +12 -0
- package/src/tests/samples/protocol13.py +26 -0
- package/src/tests/samples/protocol14.py +27 -0
- package/src/tests/samples/protocol15.py +27 -0
- package/src/tests/samples/protocol16.py +22 -0
- package/src/tests/samples/protocol17.py +94 -0
- package/src/tests/samples/protocol18.py +27 -0
- package/src/tests/samples/protocol19.py +39 -0
- package/src/tests/samples/protocol2.py +38 -0
- package/src/tests/samples/protocol20.py +22 -0
- package/src/tests/samples/protocol21.py +26 -0
- package/src/tests/samples/protocol22.py +43 -0
- package/src/tests/samples/protocol23.py +41 -0
- package/src/tests/samples/protocol24.py +74 -0
- package/src/tests/samples/protocol25.py +31 -0
- package/src/tests/samples/protocol26.py +40 -0
- package/src/tests/samples/protocol27.py +76 -0
- package/src/tests/samples/protocol28.py +32 -0
- package/src/tests/samples/protocol29.py +26 -0
- package/src/tests/samples/protocol3.py +110 -0
- package/src/tests/samples/protocol30.py +30 -0
- package/src/tests/samples/protocol31.py +22 -0
- package/src/tests/samples/protocol32.py +67 -0
- package/src/tests/samples/protocol33.py +39 -0
- package/src/tests/samples/protocol34.py +21 -0
- package/src/tests/samples/protocol4.py +22 -0
- package/src/tests/samples/protocol5.py +25 -0
- package/src/tests/samples/protocol6.py +65 -0
- package/src/tests/samples/protocol7.py +24 -0
- package/src/tests/samples/protocol8.py +34 -0
- package/src/tests/samples/protocol9.py +35 -0
- package/src/tests/samples/protocolModule1.py +15 -0
- package/src/tests/samples/protocolModule2.py +83 -0
- package/src/tests/samples/protocolModule3.py +14 -0
- package/src/tests/samples/protocolModule4.py +26 -0
- package/src/tests/samples/pseudoGeneric1.py +20 -0
- package/src/tests/samples/pyrightIgnore1.py +11 -0
- package/src/tests/samples/pyrightIgnore2.py +24 -0
- package/src/tests/samples/python2.py +31 -0
- package/src/tests/samples/recursiveTypeAlias1.py +79 -0
- package/src/tests/samples/recursiveTypeAlias2.py +32 -0
- package/src/tests/samples/recursiveTypeAlias3.py +26 -0
- package/src/tests/samples/recursiveTypeAlias4.py +55 -0
- package/src/tests/samples/recursiveTypeAlias5.pyi +10 -0
- package/src/tests/samples/recursiveTypeAlias6.py +25 -0
- package/src/tests/samples/recursiveTypeAlias7.py +15 -0
- package/src/tests/samples/recursiveTypeAlias8.py +38 -0
- package/src/tests/samples/recursiveTypeAlias9.py +22 -0
- package/src/tests/samples/required1.py +47 -0
- package/src/tests/samples/required2.py +56 -0
- package/src/tests/samples/required3.py +22 -0
- package/src/tests/samples/returnTypes1.py +26 -0
- package/src/tests/samples/revealedType1.py +30 -0
- package/src/tests/samples/sample1.py +6 -0
- package/src/tests/samples/self1.py +93 -0
- package/src/tests/samples/self2.py +195 -0
- package/src/tests/samples/self3.py +9 -0
- package/src/tests/samples/self4.py +18 -0
- package/src/tests/samples/self5.py +26 -0
- package/src/tests/samples/setComprehension1.py +34 -0
- package/src/tests/samples/slots1.py +63 -0
- package/src/tests/samples/slots2.py +38 -0
- package/src/tests/samples/slots3.py +35 -0
- package/src/tests/samples/specialization1.py +78 -0
- package/src/tests/samples/specialization2.py +51 -0
- package/src/tests/samples/staticExpressions1.py +52 -0
- package/src/tests/samples/strings1.py +22 -0
- package/src/tests/samples/subscript1.py +74 -0
- package/src/tests/samples/subscript2.py +55 -0
- package/src/tests/samples/subscript3.py +135 -0
- package/src/tests/samples/suiteExpectedColon1.py +4 -0
- package/src/tests/samples/suiteExpectedColon2.py +2 -0
- package/src/tests/samples/suiteExpectedColon3.py +2 -0
- package/src/tests/samples/super1.py +57 -0
- package/src/tests/samples/super2.py +29 -0
- package/src/tests/samples/super3.py +10 -0
- package/src/tests/samples/super4.py +24 -0
- package/src/tests/samples/super5.py +28 -0
- package/src/tests/samples/super6.py +17 -0
- package/src/tests/samples/super7.py +52 -0
- package/src/tests/samples/super8.py +7 -0
- package/src/tests/samples/super9.py +36 -0
- package/src/tests/samples/test_file1.py +0 -0
- package/src/tests/samples/threePartVersion1.py +33 -0
- package/src/tests/samples/totalOrdering1.py +52 -0
- package/src/tests/samples/tryExcept1.py +39 -0
- package/src/tests/samples/tryExcept10.py +12 -0
- package/src/tests/samples/tryExcept2.py +16 -0
- package/src/tests/samples/tryExcept3.py +12 -0
- package/src/tests/samples/tryExcept4.py +28 -0
- package/src/tests/samples/tryExcept5.py +30 -0
- package/src/tests/samples/tryExcept6.py +27 -0
- package/src/tests/samples/tryExcept7.py +17 -0
- package/src/tests/samples/tryExcept8.py +69 -0
- package/src/tests/samples/tryExcept9.py +42 -0
- package/src/tests/samples/tupleUnpack1.py +63 -0
- package/src/tests/samples/tupleUnpack2.py +56 -0
- package/src/tests/samples/tupleUnpack3.py +28 -0
- package/src/tests/samples/tuples1.py +185 -0
- package/src/tests/samples/tuples10.py +30 -0
- package/src/tests/samples/tuples11.py +21 -0
- package/src/tests/samples/tuples12.py +31 -0
- package/src/tests/samples/tuples13.py +26 -0
- package/src/tests/samples/tuples15.py +16 -0
- package/src/tests/samples/tuples16.py +14 -0
- package/src/tests/samples/tuples2.py +23 -0
- package/src/tests/samples/tuples3.py +15 -0
- package/src/tests/samples/tuples4.py +21 -0
- package/src/tests/samples/tuples5.py +16 -0
- package/src/tests/samples/tuples6.py +56 -0
- package/src/tests/samples/tuples7.py +61 -0
- package/src/tests/samples/tuples8.py +98 -0
- package/src/tests/samples/tuples9.py +17 -0
- package/src/tests/samples/typeAlias1.py +37 -0
- package/src/tests/samples/typeAlias10.py +45 -0
- package/src/tests/samples/typeAlias11.py +37 -0
- package/src/tests/samples/typeAlias12.py +20 -0
- package/src/tests/samples/typeAlias13.py +53 -0
- package/src/tests/samples/typeAlias14.py +29 -0
- package/src/tests/samples/typeAlias15.py +24 -0
- package/src/tests/samples/typeAlias16.py +24 -0
- package/src/tests/samples/typeAlias2.py +26 -0
- package/src/tests/samples/typeAlias3.py +35 -0
- package/src/tests/samples/typeAlias4.py +68 -0
- package/src/tests/samples/typeAlias5.py +56 -0
- package/src/tests/samples/typeAlias6.py +51 -0
- package/src/tests/samples/typeAlias7.py +50 -0
- package/src/tests/samples/typeAlias8.py +24 -0
- package/src/tests/samples/typeAlias9.py +35 -0
- package/src/tests/samples/typeGuard1.py +68 -0
- package/src/tests/samples/typeGuard2.py +58 -0
- package/src/tests/samples/typeGuard3.py +98 -0
- package/src/tests/samples/typeIgnore1.py +10 -0
- package/src/tests/samples/typeIgnore2.py +20 -0
- package/src/tests/samples/typeIgnore3.py +22 -0
- package/src/tests/samples/typeIgnore4.py +10 -0
- package/src/tests/samples/typeIgnore5.py +7 -0
- package/src/tests/samples/typeNarrowing1.py +56 -0
- package/src/tests/samples/typeNarrowing2.py +14 -0
- package/src/tests/samples/typeNarrowing3.py +47 -0
- package/src/tests/samples/typeNarrowing4.py +24 -0
- package/src/tests/samples/typeNarrowing5.py +19 -0
- package/src/tests/samples/typeNarrowing6.py +27 -0
- package/src/tests/samples/typeNarrowing7.py +71 -0
- package/src/tests/samples/typeNarrowingAssert1.py +24 -0
- package/src/tests/samples/typeNarrowingCallable1.py +78 -0
- package/src/tests/samples/typeNarrowingEnum1.py +58 -0
- package/src/tests/samples/typeNarrowingEnum2.py +71 -0
- package/src/tests/samples/typeNarrowingFalsy1.py +50 -0
- package/src/tests/samples/typeNarrowingIn1.py +97 -0
- package/src/tests/samples/typeNarrowingIsNone1.py +56 -0
- package/src/tests/samples/typeNarrowingIsNone2.py +8 -0
- package/src/tests/samples/typeNarrowingIsNoneTuple1.py +42 -0
- package/src/tests/samples/typeNarrowingIsNoneTuple2.py +35 -0
- package/src/tests/samples/typeNarrowingIsinstance1.py +162 -0
- package/src/tests/samples/typeNarrowingIsinstance2.py +14 -0
- package/src/tests/samples/typeNarrowingIsinstance3.py +78 -0
- package/src/tests/samples/typeNarrowingIsinstance4.py +50 -0
- package/src/tests/samples/typeNarrowingIsinstance5.py +39 -0
- package/src/tests/samples/typeNarrowingIsinstance6.py +77 -0
- package/src/tests/samples/typeNarrowingIsinstance7.py +19 -0
- package/src/tests/samples/typeNarrowingIsinstance8.py +19 -0
- package/src/tests/samples/typeNarrowingLiteral1.py +35 -0
- package/src/tests/samples/typeNarrowingLiteral2.py +63 -0
- package/src/tests/samples/typeNarrowingLiteralMember1.py +140 -0
- package/src/tests/samples/typeNarrowingLocalConst1.py +136 -0
- package/src/tests/samples/typeNarrowingNoneMember1.py +102 -0
- package/src/tests/samples/typeNarrowingTuple1.py +23 -0
- package/src/tests/samples/typeNarrowingTupleLength1.py +47 -0
- package/src/tests/samples/typeNarrowingTypeIs1.py +95 -0
- package/src/tests/samples/typeNarrowingTypedDict1.py +99 -0
- package/src/tests/samples/typeNarrowingTypedDict2.py +35 -0
- package/src/tests/samples/typeNarrowingTypedDict3.py +45 -0
- package/src/tests/samples/typePromotions1.py +30 -0
- package/src/tests/samples/typeVar1.py +23 -0
- package/src/tests/samples/typeVar10.py +21 -0
- package/src/tests/samples/typeVar11.py +12 -0
- package/src/tests/samples/typeVar2.py +26 -0
- package/src/tests/samples/typeVar3.py +73 -0
- package/src/tests/samples/typeVar4.py +45 -0
- package/src/tests/samples/typeVar5.py +75 -0
- package/src/tests/samples/typeVar6.py +115 -0
- package/src/tests/samples/typeVar7.py +171 -0
- package/src/tests/samples/typeVar8.py +30 -0
- package/src/tests/samples/typeVar9.py +118 -0
- package/src/tests/samples/typedDict1.py +63 -0
- package/src/tests/samples/typedDict10.py +34 -0
- package/src/tests/samples/typedDict11.py +12 -0
- package/src/tests/samples/typedDict12.py +103 -0
- package/src/tests/samples/typedDict13.py +14 -0
- package/src/tests/samples/typedDict14.py +25 -0
- package/src/tests/samples/typedDict15.py +53 -0
- package/src/tests/samples/typedDict16.py +103 -0
- package/src/tests/samples/typedDict17.py +24 -0
- package/src/tests/samples/typedDict18.py +43 -0
- package/src/tests/samples/typedDict2.py +56 -0
- package/src/tests/samples/typedDict3.py +40 -0
- package/src/tests/samples/typedDict4.py +68 -0
- package/src/tests/samples/typedDict5.py +50 -0
- package/src/tests/samples/typedDict6.py +77 -0
- package/src/tests/samples/typedDict7.py +22 -0
- package/src/tests/samples/typedDict8.py +19 -0
- package/src/tests/samples/typedDict9.py +22 -0
- package/src/tests/samples/unbound1.py +18 -0
- package/src/tests/samples/unbound2.py +12 -0
- package/src/tests/samples/unbound3.py +13 -0
- package/src/tests/samples/unbound4.py +25 -0
- package/src/tests/samples/unicode1.py +39 -0
- package/src/tests/samples/uninitializedVariable1.py +27 -0
- package/src/tests/samples/unions1.py +79 -0
- package/src/tests/samples/unions2.py +15 -0
- package/src/tests/samples/unions3.py +48 -0
- package/src/tests/samples/unions4.py +20 -0
- package/src/tests/samples/unions5.py +43 -0
- package/src/tests/samples/unnecessaryCast1.py +13 -0
- package/src/tests/samples/unnecessaryIsInstance1.py +91 -0
- package/src/tests/samples/unnecessaryIsSubclass1.py +22 -0
- package/src/tests/samples/unpack1.py +56 -0
- package/src/tests/samples/unpack2.py +27 -0
- package/src/tests/samples/unpack3.py +16 -0
- package/src/tests/samples/unpack4.py +15 -0
- package/src/tests/samples/unreachable1.py +112 -0
- package/src/tests/samples/unusedCallResult1.py +67 -0
- package/src/tests/samples/unusedCoroutine1.py +23 -0
- package/src/tests/samples/unusedExpression1.py +34 -0
- package/src/tests/samples/unusedVariable1.py +21 -0
- package/src/tests/samples/variadicTypeVar1.py +51 -0
- package/src/tests/samples/variadicTypeVar10.py +65 -0
- package/src/tests/samples/variadicTypeVar11.py +72 -0
- package/src/tests/samples/variadicTypeVar12.py +26 -0
- package/src/tests/samples/variadicTypeVar13.py +35 -0
- package/src/tests/samples/variadicTypeVar14.py +72 -0
- package/src/tests/samples/variadicTypeVar2.py +63 -0
- package/src/tests/samples/variadicTypeVar3.py +86 -0
- package/src/tests/samples/variadicTypeVar4.py +71 -0
- package/src/tests/samples/variadicTypeVar5.py +131 -0
- package/src/tests/samples/variadicTypeVar6.py +78 -0
- package/src/tests/samples/variadicTypeVar7.py +59 -0
- package/src/tests/samples/variadicTypeVar8.py +116 -0
- package/src/tests/samples/variadicTypeVar9.py +38 -0
- package/src/tests/samples/with1.py +117 -0
- package/src/tests/samples/with2.py +63 -0
- package/src/tests/samples/with3.py +66 -0
- package/src/tests/samples/with4.py +24 -0
- package/src/tests/samples/with5.py +33 -0
- package/src/tests/samples/zipfs/bad.egg +1 -0
- package/src/tests/samples/zipfs/bad.zip +1 -0
- package/src/tests/samples/zipfs/basic.egg +0 -0
- package/src/tests/samples/zipfs/basic.zip +0 -0
- package/src/tests/samples/zipfs/corrupt.egg +0 -0
- package/src/tests/samples/zipfs/corrupt.zip +0 -0
- package/src/tests/sourceFile.test.ts +25 -0
- package/src/tests/stringUtils.test.ts +63 -0
- package/src/tests/symbolNameUtils.test.ts +77 -0
- package/src/tests/testState.test.ts +579 -0
- package/src/tests/testUtils.ts +251 -0
- package/src/tests/tokenizer.test.ts +1534 -0
- package/src/tests/typeEvaluator1.test.ts +1372 -0
- package/src/tests/typeEvaluator2.test.ts +1253 -0
- package/src/tests/typeEvaluator3.test.ts +1279 -0
- package/src/tests/typeEvaluator4.test.ts +1178 -0
- package/src/tests/updateSymbolReference.test.ts +1107 -0
- package/src/tests/zipfs.test.ts +116 -0
- package/src/workspaceMap.ts +76 -0
@@ -0,0 +1,1893 @@
|
|
1
|
+
/*
|
2
|
+
* filesystem.ts
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
4
|
+
* Licensed under the MIT license.
|
5
|
+
*
|
6
|
+
* virtual file system implementation
|
7
|
+
*/
|
8
|
+
|
9
|
+
/* eslint-disable no-dupe-class-members */
|
10
|
+
import { Dirent, ReadStream, WriteStream } from 'fs';
|
11
|
+
import { URI } from 'vscode-uri';
|
12
|
+
|
13
|
+
import { FileSystem, FileWatcher, FileWatcherEventHandler, TmpfileOptions } from '../../../common/fileSystem';
|
14
|
+
import * as pathUtil from '../../../common/pathUtils';
|
15
|
+
import { bufferFrom, createIOError } from '../utils';
|
16
|
+
import { closeIterator, getIterator, Metadata, nextResult, SortedMap } from './../utils';
|
17
|
+
import { validate, ValidationFlags } from './pathValidation';
|
18
|
+
|
19
|
+
export const MODULE_PATH = pathUtil.normalizeSlashes('/');
|
20
|
+
|
21
|
+
let devCount = 0; // A monotonically increasing count of device ids
|
22
|
+
let inoCount = 0; // A monotonically increasing count of inodes
|
23
|
+
|
24
|
+
export interface DiffOptions {
|
25
|
+
includeChangedFileWithSameContent?: boolean;
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Represents a virtual POSIX-like file system.
|
30
|
+
*/
|
31
|
+
export class TestFileSystem implements FileSystem {
|
32
|
+
/** Indicates whether the file system is case-sensitive (`false`) or case-insensitive (`true`). */
|
33
|
+
readonly ignoreCase: boolean;
|
34
|
+
|
35
|
+
/** Gets the comparison function used to compare two paths. */
|
36
|
+
readonly stringComparer: (a: string, b: string) => number;
|
37
|
+
|
38
|
+
// lazy-initialized state that should be mutable even if the FileSystem is frozen.
|
39
|
+
private _lazy: {
|
40
|
+
links?: SortedMap<string, Inode>;
|
41
|
+
shadows?: Map<number, Inode>;
|
42
|
+
meta?: Metadata;
|
43
|
+
} = {};
|
44
|
+
|
45
|
+
private _cwd: string; // current working directory
|
46
|
+
private _time: number | Date | (() => number | Date);
|
47
|
+
private _shadowRoot: TestFileSystem | undefined;
|
48
|
+
private _dirStack: string[] | undefined;
|
49
|
+
private _tmpfileCounter = 0;
|
50
|
+
|
51
|
+
constructor(ignoreCase: boolean, options: FileSystemOptions = {}) {
|
52
|
+
const { time = -1, files, meta } = options;
|
53
|
+
this.ignoreCase = ignoreCase;
|
54
|
+
this.stringComparer = this.ignoreCase
|
55
|
+
? pathUtil.comparePathsCaseInsensitive
|
56
|
+
: pathUtil.comparePathsCaseSensitive;
|
57
|
+
this._time = time;
|
58
|
+
|
59
|
+
if (meta) {
|
60
|
+
for (const key of Object.keys(meta)) {
|
61
|
+
this.meta.set(key, meta[key]);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
if (files) {
|
66
|
+
this._applyFiles(files, /*dirname*/ '');
|
67
|
+
}
|
68
|
+
|
69
|
+
let cwd = options.cwd;
|
70
|
+
if ((!cwd || !pathUtil.isDiskPathRoot(cwd)) && this._lazy.links) {
|
71
|
+
const iterator = getIterator(this._lazy.links.keys());
|
72
|
+
try {
|
73
|
+
for (let i = nextResult(iterator); i; i = nextResult(iterator)) {
|
74
|
+
const name = i.value;
|
75
|
+
cwd = cwd ? pathUtil.resolvePaths(name, cwd) : name;
|
76
|
+
break;
|
77
|
+
}
|
78
|
+
} finally {
|
79
|
+
closeIterator(iterator);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
if (cwd) {
|
84
|
+
validate(cwd, ValidationFlags.Absolute);
|
85
|
+
this.mkdirpSync(cwd);
|
86
|
+
}
|
87
|
+
|
88
|
+
this._cwd = cwd || '';
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Gets metadata for this `FileSystem`.
|
93
|
+
*/
|
94
|
+
get meta(): Metadata {
|
95
|
+
if (!this._lazy.meta) {
|
96
|
+
this._lazy.meta = new Metadata(this._shadowRoot ? this._shadowRoot.meta : undefined);
|
97
|
+
}
|
98
|
+
return this._lazy.meta;
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Gets a value indicating whether the file system is read-only.
|
103
|
+
*/
|
104
|
+
get isReadonly() {
|
105
|
+
return Object.isFrozen(this);
|
106
|
+
}
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Makes the file system read-only.
|
110
|
+
*/
|
111
|
+
makeReadonly() {
|
112
|
+
Object.freeze(this);
|
113
|
+
return this;
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Gets the file system shadowed by this file system.
|
118
|
+
*/
|
119
|
+
get shadowRoot() {
|
120
|
+
return this._shadowRoot;
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Snapshots the current file system, effectively shadowing itself. This is useful for
|
125
|
+
* generating file system patches using `.diff()` from one snapshot to the next. Performs
|
126
|
+
* no action if this file system is read-only.
|
127
|
+
*/
|
128
|
+
snapshot() {
|
129
|
+
if (this.isReadonly) {
|
130
|
+
return;
|
131
|
+
}
|
132
|
+
const fs = new TestFileSystem(this.ignoreCase, { time: this._time });
|
133
|
+
fs._lazy = this._lazy;
|
134
|
+
fs._cwd = this._cwd;
|
135
|
+
fs._time = this._time;
|
136
|
+
fs._shadowRoot = this._shadowRoot;
|
137
|
+
fs._dirStack = this._dirStack;
|
138
|
+
fs.makeReadonly();
|
139
|
+
this._lazy = {};
|
140
|
+
this._shadowRoot = fs;
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Gets a shadow copy of this file system. Changes to the shadow copy do not affect the
|
145
|
+
* original, allowing multiple copies of the same core file system without multiple copies
|
146
|
+
* of the same data.
|
147
|
+
*/
|
148
|
+
shadow(ignoreCase = this.ignoreCase) {
|
149
|
+
if (!this.isReadonly) {
|
150
|
+
throw new Error('Cannot shadow a mutable file system.');
|
151
|
+
}
|
152
|
+
if (ignoreCase && !this.ignoreCase) {
|
153
|
+
throw new Error('Cannot create a case-insensitive file system from a case-sensitive one.');
|
154
|
+
}
|
155
|
+
const fs = new TestFileSystem(ignoreCase, { time: this._time });
|
156
|
+
fs._shadowRoot = this;
|
157
|
+
fs._cwd = this._cwd;
|
158
|
+
return fs;
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Gets or sets the timestamp (in milliseconds) used for file status, returning the previous timestamp.
|
163
|
+
*
|
164
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
|
165
|
+
*/
|
166
|
+
time(value?: number | Date | (() => number | Date)): number {
|
167
|
+
if (value !== undefined && this.isReadonly) {
|
168
|
+
throw createIOError('EPERM');
|
169
|
+
}
|
170
|
+
let result = this._time;
|
171
|
+
if (typeof result === 'function') {
|
172
|
+
result = result();
|
173
|
+
}
|
174
|
+
if (typeof result === 'object') {
|
175
|
+
result = result.getTime();
|
176
|
+
}
|
177
|
+
if (result === -1) {
|
178
|
+
result = Date.now();
|
179
|
+
}
|
180
|
+
if (value !== undefined) {
|
181
|
+
this._time = value;
|
182
|
+
}
|
183
|
+
return result;
|
184
|
+
}
|
185
|
+
|
186
|
+
/**
|
187
|
+
* Gets the metadata object for a path.
|
188
|
+
* @param path
|
189
|
+
*/
|
190
|
+
filemeta(path: string): Metadata {
|
191
|
+
const { node } = this._walk(this._resolve(path));
|
192
|
+
if (!node) {
|
193
|
+
throw createIOError('ENOENT');
|
194
|
+
}
|
195
|
+
return this._filemeta(node);
|
196
|
+
}
|
197
|
+
|
198
|
+
private _filemeta(node: Inode): Metadata {
|
199
|
+
if (!node.meta) {
|
200
|
+
const parentMeta = node.shadowRoot && this._shadowRoot && this._shadowRoot._filemeta(node.shadowRoot);
|
201
|
+
node.meta = new Metadata(parentMeta);
|
202
|
+
}
|
203
|
+
return node.meta;
|
204
|
+
}
|
205
|
+
|
206
|
+
/**
|
207
|
+
* Get the pathname of the current working directory.
|
208
|
+
*
|
209
|
+
* @link - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html
|
210
|
+
*/
|
211
|
+
cwd() {
|
212
|
+
if (!this._cwd) {
|
213
|
+
throw new Error('The current working directory has not been set.');
|
214
|
+
}
|
215
|
+
const { node } = this._walk(this._cwd);
|
216
|
+
if (!node) {
|
217
|
+
throw createIOError('ENOENT');
|
218
|
+
}
|
219
|
+
if (!isDirectory(node)) {
|
220
|
+
throw createIOError('ENOTDIR');
|
221
|
+
}
|
222
|
+
return this._cwd;
|
223
|
+
}
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Changes the current working directory.
|
227
|
+
*
|
228
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html
|
229
|
+
*/
|
230
|
+
chdir(path: string) {
|
231
|
+
if (this.isReadonly) {
|
232
|
+
throw createIOError('EPERM');
|
233
|
+
}
|
234
|
+
path = this._resolve(path);
|
235
|
+
const { node } = this._walk(path);
|
236
|
+
if (!node) {
|
237
|
+
throw createIOError('ENOENT');
|
238
|
+
}
|
239
|
+
if (!isDirectory(node)) {
|
240
|
+
throw createIOError('ENOTDIR');
|
241
|
+
}
|
242
|
+
this._cwd = path;
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Pushes the current directory onto the directory stack and changes the current working directory to the supplied path.
|
247
|
+
*/
|
248
|
+
pushd(path?: string) {
|
249
|
+
if (this.isReadonly) {
|
250
|
+
throw createIOError('EPERM');
|
251
|
+
}
|
252
|
+
if (path) {
|
253
|
+
path = this._resolve(path);
|
254
|
+
}
|
255
|
+
if (this._cwd) {
|
256
|
+
if (!this._dirStack) {
|
257
|
+
this._dirStack = [];
|
258
|
+
}
|
259
|
+
this._dirStack.push(this._cwd);
|
260
|
+
}
|
261
|
+
if (path && path !== this._cwd) {
|
262
|
+
this.chdir(path);
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Pops the previous directory from the location stack and changes the current directory to that directory.
|
268
|
+
*/
|
269
|
+
popd() {
|
270
|
+
if (this.isReadonly) {
|
271
|
+
throw createIOError('EPERM');
|
272
|
+
}
|
273
|
+
const path = this._dirStack && this._dirStack.pop();
|
274
|
+
if (path) {
|
275
|
+
this.chdir(path);
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Update the file system with a set of files.
|
281
|
+
*/
|
282
|
+
apply(files: FileSet) {
|
283
|
+
this._applyFiles(files, this._cwd);
|
284
|
+
}
|
285
|
+
|
286
|
+
/**
|
287
|
+
* Scan file system entries along a path. If `path` is a symbolic link, it is dereferenced.
|
288
|
+
* @param path The path at which to start the scan.
|
289
|
+
* @param axis The axis along which to traverse.
|
290
|
+
* @param traversal The traversal scheme to use.
|
291
|
+
*/
|
292
|
+
scanSync(path: string, axis: Axis, traversal: Traversal) {
|
293
|
+
path = this._resolve(path);
|
294
|
+
const results: string[] = [];
|
295
|
+
this._scan(path, this._stat(this._walk(path)), axis, traversal, /*noFollow*/ false, results);
|
296
|
+
return results;
|
297
|
+
}
|
298
|
+
|
299
|
+
/**
|
300
|
+
* Scan file system entries along a path.
|
301
|
+
* @param path The path at which to start the scan.
|
302
|
+
* @param axis The axis along which to traverse.
|
303
|
+
* @param traversal The traversal scheme to use.
|
304
|
+
*/
|
305
|
+
lscanSync(path: string, axis: Axis, traversal: Traversal) {
|
306
|
+
path = this._resolve(path);
|
307
|
+
const results: string[] = [];
|
308
|
+
this._scan(path, this._stat(this._walk(path, /*noFollow*/ true)), axis, traversal, /*noFollow*/ true, results);
|
309
|
+
return results;
|
310
|
+
}
|
311
|
+
|
312
|
+
createFileSystemWatcher(paths: string[], listener: FileWatcherEventHandler): FileWatcher {
|
313
|
+
return {
|
314
|
+
close: () => {
|
315
|
+
/* left empty */
|
316
|
+
},
|
317
|
+
};
|
318
|
+
}
|
319
|
+
|
320
|
+
getModulePath(): string {
|
321
|
+
return MODULE_PATH;
|
322
|
+
}
|
323
|
+
|
324
|
+
tmpdir(): string {
|
325
|
+
this.mkdirpSync('/tmp');
|
326
|
+
return pathUtil.normalizeSlashes('/tmp');
|
327
|
+
}
|
328
|
+
|
329
|
+
tmpfile(options?: TmpfileOptions): string {
|
330
|
+
// Use an algorithm similar to tmp's.
|
331
|
+
const prefix = options?.prefix || 'tmp';
|
332
|
+
const postfix = options?.prefix ? '-' + options.prefix : '';
|
333
|
+
const name = `${prefix}-${this._tmpfileCounter++}${postfix}`;
|
334
|
+
const path = pathUtil.combinePaths(this.tmpdir(), name);
|
335
|
+
this.writeFileSync(path, '');
|
336
|
+
return path;
|
337
|
+
}
|
338
|
+
|
339
|
+
realCasePath(path: string): string {
|
340
|
+
return path;
|
341
|
+
}
|
342
|
+
|
343
|
+
isMappedFilePath(filepath: string): boolean {
|
344
|
+
return false;
|
345
|
+
}
|
346
|
+
|
347
|
+
// Get original filepath if the given filepath is mapped.
|
348
|
+
getOriginalFilePath(mappedFilePath: string) {
|
349
|
+
return mappedFilePath;
|
350
|
+
}
|
351
|
+
|
352
|
+
// Get mapped filepath if the given filepath is mapped.
|
353
|
+
getMappedFilePath(originalFilepath: string) {
|
354
|
+
return originalFilepath;
|
355
|
+
}
|
356
|
+
|
357
|
+
getUri(path: string): string {
|
358
|
+
return URI.file(path).toString();
|
359
|
+
}
|
360
|
+
|
361
|
+
private _scan(path: string, stats: Stats, axis: Axis, traversal: Traversal, noFollow: boolean, results: string[]) {
|
362
|
+
if (axis === 'ancestors-or-self' || axis === 'self' || axis === 'descendants-or-self') {
|
363
|
+
if (!traversal.accept || traversal.accept(path, stats)) {
|
364
|
+
results.push(path);
|
365
|
+
}
|
366
|
+
}
|
367
|
+
if (axis === 'ancestors-or-self' || axis === 'ancestors') {
|
368
|
+
const dirname = pathUtil.getDirectoryPath(path);
|
369
|
+
if (dirname !== path) {
|
370
|
+
try {
|
371
|
+
const stats = this._stat(this._walk(dirname, noFollow));
|
372
|
+
if (!traversal.traverse || traversal.traverse(dirname, stats)) {
|
373
|
+
this._scan(dirname, stats, 'ancestors-or-self', traversal, noFollow, results);
|
374
|
+
}
|
375
|
+
} catch {
|
376
|
+
/*ignored*/
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
if (axis === 'descendants-or-self' || axis === 'descendants') {
|
381
|
+
if (stats.isDirectory() && (!traversal.traverse || traversal.traverse(path, stats))) {
|
382
|
+
for (const file of this.readdirSync(path)) {
|
383
|
+
try {
|
384
|
+
const childpath = pathUtil.combinePaths(path, file);
|
385
|
+
const stats = this._stat(this._walk(childpath, noFollow));
|
386
|
+
this._scan(childpath, stats, 'descendants-or-self', traversal, noFollow, results);
|
387
|
+
} catch {
|
388
|
+
/*ignored*/
|
389
|
+
}
|
390
|
+
}
|
391
|
+
}
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Mounts a physical or virtual file system at a location in this virtual file system.
|
397
|
+
*
|
398
|
+
* @param source The path in the physical (or other virtual) file system.
|
399
|
+
* @param target The path in this virtual file system.
|
400
|
+
* @param resolver An object used to resolve files in `source`.
|
401
|
+
*/
|
402
|
+
mountSync(source: string, target: string, resolver: FileSystemResolver) {
|
403
|
+
if (this.isReadonly) {
|
404
|
+
throw createIOError('EROFS');
|
405
|
+
}
|
406
|
+
|
407
|
+
source = validate(source, ValidationFlags.Absolute);
|
408
|
+
|
409
|
+
const { parent, links, node: existingNode, basename } = this._walk(this._resolve(target), /*noFollow*/ true);
|
410
|
+
if (existingNode) {
|
411
|
+
throw createIOError('EEXIST');
|
412
|
+
}
|
413
|
+
|
414
|
+
const time = this.time();
|
415
|
+
const node = this._mknod(parent ? parent.dev : ++devCount, S_IFDIR, /*mode*/ 0o777, time);
|
416
|
+
node.source = source;
|
417
|
+
node.resolver = resolver;
|
418
|
+
this._addLink(parent, links, basename, node, time);
|
419
|
+
}
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Recursively remove all files and directories underneath the provided path.
|
423
|
+
*/
|
424
|
+
rimrafSync(path: string) {
|
425
|
+
try {
|
426
|
+
const stats = this.lstatSync(path);
|
427
|
+
if (stats.isFile() || stats.isSymbolicLink()) {
|
428
|
+
this.unlinkSync(path);
|
429
|
+
} else if (stats.isDirectory()) {
|
430
|
+
for (const file of this.readdirSync(path)) {
|
431
|
+
this.rimrafSync(pathUtil.combinePaths(path, file));
|
432
|
+
}
|
433
|
+
this.rmdirSync(path);
|
434
|
+
}
|
435
|
+
} catch (e: any) {
|
436
|
+
if (e.code === 'ENOENT') {
|
437
|
+
return;
|
438
|
+
}
|
439
|
+
throw e;
|
440
|
+
}
|
441
|
+
}
|
442
|
+
|
443
|
+
/**
|
444
|
+
* Make a directory and all of its parent paths (if they don't exist).
|
445
|
+
*/
|
446
|
+
mkdirpSync(path: string) {
|
447
|
+
path = this._resolve(path);
|
448
|
+
const result = this._walk(path, /*noFollow*/ true, (error, result) => {
|
449
|
+
if (error.code === 'ENOENT') {
|
450
|
+
this._mkdir(result);
|
451
|
+
return 'retry';
|
452
|
+
}
|
453
|
+
return 'throw';
|
454
|
+
});
|
455
|
+
|
456
|
+
if (!result.node) {
|
457
|
+
this._mkdir(result);
|
458
|
+
}
|
459
|
+
}
|
460
|
+
|
461
|
+
getFileListing(): string {
|
462
|
+
let result = '';
|
463
|
+
const printLinks = (dirname: string | undefined, links: SortedMap<string, Inode>) => {
|
464
|
+
const iterator = getIterator(links);
|
465
|
+
try {
|
466
|
+
for (let i = nextResult(iterator); i; i = nextResult(iterator)) {
|
467
|
+
const [name, node] = i.value;
|
468
|
+
const path = dirname ? pathUtil.combinePaths(dirname, name) : name;
|
469
|
+
const marker = pathUtil.comparePaths(this._cwd, path, this.ignoreCase) === 0 ? '*' : ' ';
|
470
|
+
if (result) {
|
471
|
+
result += '\n';
|
472
|
+
}
|
473
|
+
result += marker;
|
474
|
+
if (isDirectory(node)) {
|
475
|
+
result += pathUtil.ensureTrailingDirectorySeparator(path);
|
476
|
+
printLinks(path, this._getLinks(node));
|
477
|
+
} else if (isFile(node)) {
|
478
|
+
result += path;
|
479
|
+
} else if (isSymlink(node)) {
|
480
|
+
result += `${path} -> ${node.symlink}`;
|
481
|
+
}
|
482
|
+
}
|
483
|
+
} finally {
|
484
|
+
closeIterator(iterator);
|
485
|
+
}
|
486
|
+
};
|
487
|
+
printLinks(/*dirname*/ undefined, this._getRootLinks());
|
488
|
+
return result;
|
489
|
+
}
|
490
|
+
|
491
|
+
/**
|
492
|
+
* Print diagnostic information about the structure of the file system to the console.
|
493
|
+
*/
|
494
|
+
debugPrint(): void {
|
495
|
+
console.log(this.getFileListing());
|
496
|
+
}
|
497
|
+
|
498
|
+
// POSIX API (aligns with NodeJS "fs" module API)
|
499
|
+
|
500
|
+
/**
|
501
|
+
* Determines whether a path exists.
|
502
|
+
*/
|
503
|
+
existsSync(path: string) {
|
504
|
+
const result = this._walk(this._resolve(path), /*noFollow*/ true, () => 'stop');
|
505
|
+
return result !== undefined && result.node !== undefined;
|
506
|
+
}
|
507
|
+
|
508
|
+
/**
|
509
|
+
* Get file status. If `path` is a symbolic link, it is dereferenced.
|
510
|
+
*
|
511
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
|
512
|
+
*
|
513
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
514
|
+
*/
|
515
|
+
statSync(path: string) {
|
516
|
+
return this._stat(this._walk(this._resolve(path)));
|
517
|
+
}
|
518
|
+
|
519
|
+
/**
|
520
|
+
* Change file access times
|
521
|
+
*
|
522
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
523
|
+
*/
|
524
|
+
utimesSync(path: string, atime: Date, mtime: Date) {
|
525
|
+
if (this.isReadonly) {
|
526
|
+
throw createIOError('EROFS');
|
527
|
+
}
|
528
|
+
if (!isFinite(+atime) || !isFinite(+mtime)) {
|
529
|
+
throw createIOError('EINVAL');
|
530
|
+
}
|
531
|
+
|
532
|
+
const entry = this._walk(this._resolve(path));
|
533
|
+
if (!entry || !entry.node) {
|
534
|
+
throw createIOError('ENOENT');
|
535
|
+
}
|
536
|
+
entry.node.atimeMs = +atime;
|
537
|
+
entry.node.mtimeMs = +mtime;
|
538
|
+
entry.node.ctimeMs = this.time();
|
539
|
+
}
|
540
|
+
|
541
|
+
/**
|
542
|
+
* Get file status. If `path` is a symbolic link, it is dereferenced.
|
543
|
+
*
|
544
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html
|
545
|
+
*
|
546
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
547
|
+
*/
|
548
|
+
lstatSync(path: string) {
|
549
|
+
return this._stat(this._walk(this._resolve(path), /*noFollow*/ true));
|
550
|
+
}
|
551
|
+
|
552
|
+
private _stat(entry: WalkResult) {
|
553
|
+
const node = entry.node;
|
554
|
+
if (!node) {
|
555
|
+
throw createIOError(`ENOENT`, entry.realpath);
|
556
|
+
}
|
557
|
+
return new Stats(
|
558
|
+
node.dev,
|
559
|
+
node.ino,
|
560
|
+
node.mode,
|
561
|
+
node.nlink,
|
562
|
+
/*rdev*/ 0,
|
563
|
+
/*size*/ isFile(node) ? this._getSize(node) : isSymlink(node) ? node.symlink.length : 0,
|
564
|
+
/*blksize*/ 4096,
|
565
|
+
/*blocks*/ 0,
|
566
|
+
node.atimeMs,
|
567
|
+
node.mtimeMs,
|
568
|
+
node.ctimeMs,
|
569
|
+
node.birthtimeMs
|
570
|
+
);
|
571
|
+
}
|
572
|
+
|
573
|
+
/**
|
574
|
+
* Read a directory. If `path` is a symbolic link, it is dereferenced.
|
575
|
+
*
|
576
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
|
577
|
+
*
|
578
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
579
|
+
*/
|
580
|
+
readdirSync(path: string) {
|
581
|
+
const { node } = this._walk(this._resolve(path));
|
582
|
+
if (!node) {
|
583
|
+
throw createIOError('ENOENT');
|
584
|
+
}
|
585
|
+
if (!isDirectory(node)) {
|
586
|
+
throw createIOError('ENOTDIR');
|
587
|
+
}
|
588
|
+
return Array.from(this._getLinks(node).keys());
|
589
|
+
}
|
590
|
+
|
591
|
+
/**
|
592
|
+
* Read a directory. If `path` is a symbolic link, it is dereferenced.
|
593
|
+
*
|
594
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
|
595
|
+
*
|
596
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
597
|
+
*/
|
598
|
+
readdirEntriesSync(path: string): Dirent[] {
|
599
|
+
const { node } = this._walk(this._resolve(path));
|
600
|
+
if (!node) {
|
601
|
+
throw createIOError('ENOENT');
|
602
|
+
}
|
603
|
+
if (!isDirectory(node)) {
|
604
|
+
throw createIOError('ENOTDIR');
|
605
|
+
}
|
606
|
+
const entries = Array.from(this._getLinks(node).entries());
|
607
|
+
return entries.map(([k, v]) => makeDirEnt(k, v));
|
608
|
+
}
|
609
|
+
|
610
|
+
/**
|
611
|
+
* Make a directory.
|
612
|
+
*
|
613
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html
|
614
|
+
*
|
615
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
616
|
+
*/
|
617
|
+
mkdirSync(path: string) {
|
618
|
+
if (this.isReadonly) {
|
619
|
+
throw createIOError('EROFS');
|
620
|
+
}
|
621
|
+
|
622
|
+
this._mkdir(this._walk(this._resolve(path), /*noFollow*/ true));
|
623
|
+
}
|
624
|
+
|
625
|
+
private _mkdir({ parent, links, node: existingNode, basename }: WalkResult) {
|
626
|
+
if (existingNode) {
|
627
|
+
throw createIOError('EEXIST');
|
628
|
+
}
|
629
|
+
const time = this.time();
|
630
|
+
const node = this._mknod(parent ? parent.dev : ++devCount, S_IFDIR, /*mode*/ 0o777, time);
|
631
|
+
this._addLink(parent, links, basename, node, time);
|
632
|
+
}
|
633
|
+
|
634
|
+
/**
|
635
|
+
* Remove a directory.
|
636
|
+
*
|
637
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
|
638
|
+
*
|
639
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
640
|
+
*/
|
641
|
+
rmdirSync(path: string) {
|
642
|
+
if (this.isReadonly) {
|
643
|
+
throw createIOError('EROFS');
|
644
|
+
}
|
645
|
+
path = this._resolve(path);
|
646
|
+
|
647
|
+
const { parent, links, node, basename } = this._walk(path, /*noFollow*/ true);
|
648
|
+
if (!parent) {
|
649
|
+
throw createIOError('EPERM');
|
650
|
+
}
|
651
|
+
if (!isDirectory(node)) {
|
652
|
+
throw createIOError('ENOTDIR');
|
653
|
+
}
|
654
|
+
if (this._getLinks(node).size !== 0) {
|
655
|
+
throw createIOError('ENOTEMPTY');
|
656
|
+
}
|
657
|
+
|
658
|
+
this._removeLink(parent, links, basename, node);
|
659
|
+
}
|
660
|
+
|
661
|
+
/**
|
662
|
+
* Link one file to another file (also known as a "hard link").
|
663
|
+
*
|
664
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html
|
665
|
+
*
|
666
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
667
|
+
*/
|
668
|
+
linkSync(oldpath: string, newpath: string) {
|
669
|
+
if (this.isReadonly) {
|
670
|
+
throw createIOError('EROFS');
|
671
|
+
}
|
672
|
+
|
673
|
+
const { node } = this._walk(this._resolve(oldpath));
|
674
|
+
if (!node) {
|
675
|
+
throw createIOError('ENOENT');
|
676
|
+
}
|
677
|
+
if (isDirectory(node)) {
|
678
|
+
throw createIOError('EPERM');
|
679
|
+
}
|
680
|
+
|
681
|
+
const { parent, links, basename, node: existingNode } = this._walk(this._resolve(newpath), /*noFollow*/ true);
|
682
|
+
if (!parent) {
|
683
|
+
throw createIOError('EPERM');
|
684
|
+
}
|
685
|
+
if (existingNode) {
|
686
|
+
throw createIOError('EEXIST');
|
687
|
+
}
|
688
|
+
|
689
|
+
this._addLink(parent, links, basename, node);
|
690
|
+
}
|
691
|
+
|
692
|
+
/**
|
693
|
+
* Remove a directory entry.
|
694
|
+
*
|
695
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
|
696
|
+
*
|
697
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
698
|
+
*/
|
699
|
+
unlinkSync(path: string) {
|
700
|
+
if (this.isReadonly) {
|
701
|
+
throw createIOError('EROFS');
|
702
|
+
}
|
703
|
+
|
704
|
+
const { parent, links, node, basename } = this._walk(this._resolve(path), /*noFollow*/ true);
|
705
|
+
if (!parent) {
|
706
|
+
throw createIOError('EPERM');
|
707
|
+
}
|
708
|
+
if (!node) {
|
709
|
+
throw createIOError('ENOENT');
|
710
|
+
}
|
711
|
+
if (isDirectory(node)) {
|
712
|
+
throw createIOError('EISDIR');
|
713
|
+
}
|
714
|
+
|
715
|
+
this._removeLink(parent, links, basename, node);
|
716
|
+
}
|
717
|
+
|
718
|
+
/**
|
719
|
+
* Rename a file.
|
720
|
+
*
|
721
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html
|
722
|
+
*
|
723
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
724
|
+
*/
|
725
|
+
renameSync(oldpath: string, newpath: string) {
|
726
|
+
if (this.isReadonly) {
|
727
|
+
throw createIOError('EROFS');
|
728
|
+
}
|
729
|
+
|
730
|
+
const {
|
731
|
+
parent: oldParent,
|
732
|
+
links: oldParentLinks,
|
733
|
+
node,
|
734
|
+
basename: oldBasename,
|
735
|
+
} = this._walk(this._resolve(oldpath), /*noFollow*/ true);
|
736
|
+
|
737
|
+
if (!oldParent) {
|
738
|
+
throw createIOError('EPERM');
|
739
|
+
}
|
740
|
+
if (!node) {
|
741
|
+
throw createIOError('ENOENT');
|
742
|
+
}
|
743
|
+
|
744
|
+
const {
|
745
|
+
parent: newParent,
|
746
|
+
links: newParentLinks,
|
747
|
+
node: existingNode,
|
748
|
+
basename: newBasename,
|
749
|
+
} = this._walk(this._resolve(newpath), /*noFollow*/ true);
|
750
|
+
|
751
|
+
if (!newParent) {
|
752
|
+
throw createIOError('EPERM');
|
753
|
+
}
|
754
|
+
|
755
|
+
const time = this.time();
|
756
|
+
if (existingNode) {
|
757
|
+
if (isDirectory(node)) {
|
758
|
+
if (!isDirectory(existingNode)) {
|
759
|
+
throw createIOError('ENOTDIR');
|
760
|
+
}
|
761
|
+
if (this._getLinks(existingNode).size > 0) {
|
762
|
+
throw createIOError('ENOTEMPTY');
|
763
|
+
}
|
764
|
+
} else {
|
765
|
+
if (isDirectory(existingNode)) {
|
766
|
+
throw createIOError('EISDIR');
|
767
|
+
}
|
768
|
+
}
|
769
|
+
this._removeLink(newParent, newParentLinks, newBasename, existingNode, time);
|
770
|
+
}
|
771
|
+
|
772
|
+
this._replaceLink(oldParent, oldParentLinks, oldBasename, newParent, newParentLinks, newBasename, node, time);
|
773
|
+
}
|
774
|
+
|
775
|
+
/**
|
776
|
+
* Make a symbolic link.
|
777
|
+
*
|
778
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html
|
779
|
+
*
|
780
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
781
|
+
*/
|
782
|
+
symlinkSync(target: string, linkpath: string) {
|
783
|
+
if (this.isReadonly) {
|
784
|
+
throw createIOError('EROFS');
|
785
|
+
}
|
786
|
+
|
787
|
+
const { parent, links, node: existingNode, basename } = this._walk(this._resolve(linkpath), /*noFollow*/ true);
|
788
|
+
if (!parent) {
|
789
|
+
throw createIOError('EPERM');
|
790
|
+
}
|
791
|
+
if (existingNode) {
|
792
|
+
throw createIOError('EEXIST');
|
793
|
+
}
|
794
|
+
|
795
|
+
const time = this.time();
|
796
|
+
const node = this._mknod(parent.dev, S_IFLNK, /*mode*/ 0o666, time);
|
797
|
+
node.symlink = validate(target, ValidationFlags.RelativeOrAbsolute);
|
798
|
+
this._addLink(parent, links, basename, node, time);
|
799
|
+
}
|
800
|
+
|
801
|
+
/**
|
802
|
+
* Resolve a pathname.
|
803
|
+
*
|
804
|
+
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html
|
805
|
+
*
|
806
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
807
|
+
*/
|
808
|
+
realpathSync(path: string) {
|
809
|
+
const { realpath } = this._walk(this._resolve(path));
|
810
|
+
return realpath;
|
811
|
+
}
|
812
|
+
|
813
|
+
/**
|
814
|
+
* Read from a file.
|
815
|
+
*
|
816
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
817
|
+
*/
|
818
|
+
readFileSync(path: string, encoding?: null): Buffer;
|
819
|
+
/**
|
820
|
+
* Read from a file.
|
821
|
+
*
|
822
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
823
|
+
*/
|
824
|
+
readFileSync(path: string, encoding: BufferEncoding): string;
|
825
|
+
/**
|
826
|
+
* Read from a file.
|
827
|
+
*
|
828
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
829
|
+
*/
|
830
|
+
readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer;
|
831
|
+
readFileSync(path: string, encoding: BufferEncoding | null = null) {
|
832
|
+
const { node } = this._walk(this._resolve(path));
|
833
|
+
if (!node) {
|
834
|
+
throw createIOError('ENOENT');
|
835
|
+
}
|
836
|
+
if (isDirectory(node)) {
|
837
|
+
throw createIOError('EISDIR');
|
838
|
+
}
|
839
|
+
if (!isFile(node)) {
|
840
|
+
throw createIOError('EBADF');
|
841
|
+
}
|
842
|
+
|
843
|
+
const buffer = this._getBuffer(node).slice();
|
844
|
+
return encoding ? buffer.toString(encoding) : buffer;
|
845
|
+
}
|
846
|
+
|
847
|
+
/**
|
848
|
+
* Write to a file.
|
849
|
+
*
|
850
|
+
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
851
|
+
*/
|
852
|
+
writeFileSync(path: string, data: string | Buffer, encoding: BufferEncoding | null = null) {
|
853
|
+
if (this.isReadonly) {
|
854
|
+
throw createIOError('EROFS');
|
855
|
+
}
|
856
|
+
|
857
|
+
const { parent, links, node: existingNode, basename } = this._walk(this._resolve(path), /*noFollow*/ false);
|
858
|
+
if (!parent) {
|
859
|
+
throw createIOError('EPERM');
|
860
|
+
}
|
861
|
+
|
862
|
+
const time = this.time();
|
863
|
+
let node = existingNode;
|
864
|
+
if (!node) {
|
865
|
+
node = this._mknod(parent.dev, S_IFREG, 0o666, time);
|
866
|
+
this._addLink(parent, links, basename, node, time);
|
867
|
+
}
|
868
|
+
|
869
|
+
if (isDirectory(node)) {
|
870
|
+
throw createIOError('EISDIR');
|
871
|
+
}
|
872
|
+
if (!isFile(node)) {
|
873
|
+
throw createIOError('EBADF');
|
874
|
+
}
|
875
|
+
node.buffer = Buffer.isBuffer(data)
|
876
|
+
? data.slice()
|
877
|
+
: bufferFrom('' + data, (encoding as BufferEncoding) || 'utf8');
|
878
|
+
node.size = node.buffer.byteLength;
|
879
|
+
node.mtimeMs = time;
|
880
|
+
node.ctimeMs = time;
|
881
|
+
}
|
882
|
+
|
883
|
+
readFile(filePath: string): Promise<Buffer> {
|
884
|
+
return Promise.resolve(this.readFileSync(filePath));
|
885
|
+
}
|
886
|
+
readFileText(filePath: string, encoding?: BufferEncoding): Promise<string> {
|
887
|
+
return Promise.resolve(this.readFileSync(filePath, encoding || 'utf8'));
|
888
|
+
}
|
889
|
+
|
890
|
+
createReadStream(path: string): ReadStream {
|
891
|
+
throw new Error('Not implemented in test file system.');
|
892
|
+
}
|
893
|
+
createWriteStream(path: string): WriteStream {
|
894
|
+
throw new Error('Not implemented in test file system.');
|
895
|
+
}
|
896
|
+
|
897
|
+
copyFileSync(src: string, dst: string): void {
|
898
|
+
throw new Error('Not implemented in test file system.');
|
899
|
+
}
|
900
|
+
|
901
|
+
/**
|
902
|
+
* Generates a `FileSet` patch containing all the entries in this `FileSystem` that are not in `base`.
|
903
|
+
* @param base The base file system. If not provided, this file system's `shadowRoot` is used (if present).
|
904
|
+
*/
|
905
|
+
diff(base = this.shadowRoot, options: DiffOptions = {}) {
|
906
|
+
const differences: FileSet = {};
|
907
|
+
const hasDifferences = base
|
908
|
+
? TestFileSystem._rootDiff(differences, this, base, options)
|
909
|
+
: TestFileSystem._trackCreatedInodes(differences, this, this._getRootLinks());
|
910
|
+
return hasDifferences ? differences : undefined;
|
911
|
+
}
|
912
|
+
|
913
|
+
/**
|
914
|
+
* Generates a `FileSet` patch containing all the entries in `changed` that are not in `base`.
|
915
|
+
*/
|
916
|
+
static diff(changed: TestFileSystem, base: TestFileSystem, options: DiffOptions = {}) {
|
917
|
+
const differences: FileSet = {};
|
918
|
+
return TestFileSystem._rootDiff(differences, changed, base, options) ? differences : undefined;
|
919
|
+
}
|
920
|
+
|
921
|
+
isInZipOrEgg(path: string): boolean {
|
922
|
+
return false;
|
923
|
+
}
|
924
|
+
|
925
|
+
private static _diffWorker(
|
926
|
+
container: FileSet,
|
927
|
+
changed: TestFileSystem,
|
928
|
+
changedLinks: ReadonlyMap<string, Inode> | undefined,
|
929
|
+
base: TestFileSystem,
|
930
|
+
baseLinks: ReadonlyMap<string, Inode> | undefined,
|
931
|
+
options: DiffOptions
|
932
|
+
) {
|
933
|
+
if (changedLinks && !baseLinks) {
|
934
|
+
return TestFileSystem._trackCreatedInodes(container, changed, changedLinks);
|
935
|
+
}
|
936
|
+
if (baseLinks && !changedLinks) {
|
937
|
+
return TestFileSystem._trackDeletedInodes(container, baseLinks);
|
938
|
+
}
|
939
|
+
if (changedLinks && baseLinks) {
|
940
|
+
let hasChanges = false;
|
941
|
+
// track base items missing in changed
|
942
|
+
baseLinks.forEach((node, basename) => {
|
943
|
+
if (!changedLinks.has(basename)) {
|
944
|
+
container[basename] = isDirectory(node) ? new Rmdir() : new Unlink();
|
945
|
+
hasChanges = true;
|
946
|
+
}
|
947
|
+
});
|
948
|
+
// track changed items missing or differing in base
|
949
|
+
changedLinks.forEach((changedNode, basename) => {
|
950
|
+
const baseNode = baseLinks.get(basename);
|
951
|
+
if (baseNode) {
|
952
|
+
if (isDirectory(changedNode) && isDirectory(baseNode)) {
|
953
|
+
return (hasChanges =
|
954
|
+
TestFileSystem._directoryDiff(
|
955
|
+
container,
|
956
|
+
basename,
|
957
|
+
changed,
|
958
|
+
changedNode,
|
959
|
+
base,
|
960
|
+
baseNode,
|
961
|
+
options
|
962
|
+
) || hasChanges);
|
963
|
+
}
|
964
|
+
if (isFile(changedNode) && isFile(baseNode)) {
|
965
|
+
return (hasChanges =
|
966
|
+
TestFileSystem._fileDiff(
|
967
|
+
container,
|
968
|
+
basename,
|
969
|
+
changed,
|
970
|
+
changedNode,
|
971
|
+
base,
|
972
|
+
baseNode,
|
973
|
+
options
|
974
|
+
) || hasChanges);
|
975
|
+
}
|
976
|
+
if (isSymlink(changedNode) && isSymlink(baseNode)) {
|
977
|
+
return (hasChanges =
|
978
|
+
TestFileSystem._symlinkDiff(container, basename, changedNode, baseNode) || hasChanges);
|
979
|
+
}
|
980
|
+
}
|
981
|
+
return (hasChanges =
|
982
|
+
TestFileSystem._trackCreatedInode(container, basename, changed, changedNode) || hasChanges);
|
983
|
+
});
|
984
|
+
return hasChanges;
|
985
|
+
}
|
986
|
+
return false;
|
987
|
+
}
|
988
|
+
|
989
|
+
private static _rootDiff(container: FileSet, changed: TestFileSystem, base: TestFileSystem, options: DiffOptions) {
|
990
|
+
while (!changed._lazy.links && changed._shadowRoot) {
|
991
|
+
changed = changed._shadowRoot;
|
992
|
+
}
|
993
|
+
while (!base._lazy.links && base._shadowRoot) {
|
994
|
+
base = base._shadowRoot;
|
995
|
+
}
|
996
|
+
|
997
|
+
// no difference if the file systems are the same reference
|
998
|
+
if (changed === base) {
|
999
|
+
return false;
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
// no difference if the root links are empty and unshadowed
|
1003
|
+
if (!changed._lazy.links && !changed._shadowRoot && !base._lazy.links && !base._shadowRoot) {
|
1004
|
+
return false;
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
return TestFileSystem._diffWorker(
|
1008
|
+
container,
|
1009
|
+
changed,
|
1010
|
+
changed._getRootLinks(),
|
1011
|
+
base,
|
1012
|
+
base._getRootLinks(),
|
1013
|
+
options
|
1014
|
+
);
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
private static _directoryDiff(
|
1018
|
+
container: FileSet,
|
1019
|
+
basename: string,
|
1020
|
+
changed: TestFileSystem,
|
1021
|
+
changedNode: DirectoryInode,
|
1022
|
+
base: TestFileSystem,
|
1023
|
+
baseNode: DirectoryInode,
|
1024
|
+
options: DiffOptions
|
1025
|
+
) {
|
1026
|
+
while (!changedNode.links && changedNode.shadowRoot) {
|
1027
|
+
changedNode = changedNode.shadowRoot;
|
1028
|
+
}
|
1029
|
+
while (!baseNode.links && baseNode.shadowRoot) {
|
1030
|
+
baseNode = baseNode.shadowRoot;
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
// no difference if the nodes are the same reference
|
1034
|
+
if (changedNode === baseNode) {
|
1035
|
+
return false;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
// no difference if both nodes are non shadowed and have no entries
|
1039
|
+
if (isEmptyNonShadowedDirectory(changedNode) && isEmptyNonShadowedDirectory(baseNode)) {
|
1040
|
+
return false;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
// no difference if both nodes are unpopulated and point to the same mounted file system
|
1044
|
+
if (
|
1045
|
+
!changedNode.links &&
|
1046
|
+
!baseNode.links &&
|
1047
|
+
changedNode.resolver &&
|
1048
|
+
changedNode.source !== undefined &&
|
1049
|
+
baseNode.resolver === changedNode.resolver &&
|
1050
|
+
baseNode.source === changedNode.source
|
1051
|
+
) {
|
1052
|
+
return false;
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
// no difference if both nodes have identical children
|
1056
|
+
const children: FileSet = {};
|
1057
|
+
if (
|
1058
|
+
!TestFileSystem._diffWorker(
|
1059
|
+
children,
|
1060
|
+
changed,
|
1061
|
+
changed._getLinks(changedNode),
|
1062
|
+
base,
|
1063
|
+
base._getLinks(baseNode),
|
1064
|
+
options
|
1065
|
+
)
|
1066
|
+
) {
|
1067
|
+
return false;
|
1068
|
+
}
|
1069
|
+
|
1070
|
+
container[basename] = new Directory(children);
|
1071
|
+
return true;
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
private static _fileDiff(
|
1075
|
+
container: FileSet,
|
1076
|
+
basename: string,
|
1077
|
+
changed: TestFileSystem,
|
1078
|
+
changedNode: FileInode,
|
1079
|
+
base: TestFileSystem,
|
1080
|
+
baseNode: FileInode,
|
1081
|
+
options: DiffOptions
|
1082
|
+
) {
|
1083
|
+
while (!changedNode.buffer && changedNode.shadowRoot) {
|
1084
|
+
changedNode = changedNode.shadowRoot;
|
1085
|
+
}
|
1086
|
+
while (!baseNode.buffer && baseNode.shadowRoot) {
|
1087
|
+
baseNode = baseNode.shadowRoot;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
// no difference if the nodes are the same reference
|
1091
|
+
if (changedNode === baseNode) {
|
1092
|
+
return false;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
// no difference if both nodes are non shadowed and have no entries
|
1096
|
+
if (isEmptyNonShadowedFile(changedNode) && isEmptyNonShadowedFile(baseNode)) {
|
1097
|
+
return false;
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
// no difference if both nodes are unpopulated and point to the same mounted file system
|
1101
|
+
if (
|
1102
|
+
!changedNode.buffer &&
|
1103
|
+
!baseNode.buffer &&
|
1104
|
+
changedNode.resolver &&
|
1105
|
+
changedNode.source !== undefined &&
|
1106
|
+
baseNode.resolver === changedNode.resolver &&
|
1107
|
+
baseNode.source === changedNode.source
|
1108
|
+
) {
|
1109
|
+
return false;
|
1110
|
+
}
|
1111
|
+
|
1112
|
+
const changedBuffer = changed._getBuffer(changedNode);
|
1113
|
+
const baseBuffer = base._getBuffer(baseNode);
|
1114
|
+
|
1115
|
+
// no difference if both buffers are the same reference
|
1116
|
+
if (changedBuffer === baseBuffer) {
|
1117
|
+
return false;
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
// no difference if both buffers are identical
|
1121
|
+
if (Buffer.compare(changedBuffer, baseBuffer) === 0) {
|
1122
|
+
if (!options.includeChangedFileWithSameContent) {
|
1123
|
+
return false;
|
1124
|
+
}
|
1125
|
+
container[basename] = new SameFileContentFile(changedBuffer);
|
1126
|
+
return true;
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
container[basename] = new File(changedBuffer);
|
1130
|
+
return true;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
private static _symlinkDiff(
|
1134
|
+
container: FileSet,
|
1135
|
+
basename: string,
|
1136
|
+
changedNode: SymlinkInode,
|
1137
|
+
baseNode: SymlinkInode
|
1138
|
+
) {
|
1139
|
+
// no difference if the nodes are the same reference
|
1140
|
+
if (changedNode.symlink === baseNode.symlink) {
|
1141
|
+
return false;
|
1142
|
+
}
|
1143
|
+
container[basename] = new Symlink(changedNode.symlink);
|
1144
|
+
return true;
|
1145
|
+
}
|
1146
|
+
|
1147
|
+
private static _trackCreatedInode(container: FileSet, basename: string, changed: TestFileSystem, node: Inode) {
|
1148
|
+
if (isDirectory(node)) {
|
1149
|
+
const children: FileSet = {};
|
1150
|
+
TestFileSystem._trackCreatedInodes(children, changed, changed._getLinks(node));
|
1151
|
+
container[basename] = new Directory(children);
|
1152
|
+
} else if (isSymlink(node)) {
|
1153
|
+
container[basename] = new Symlink(node.symlink);
|
1154
|
+
} else {
|
1155
|
+
container[basename] = new File(node.buffer || '');
|
1156
|
+
}
|
1157
|
+
return true;
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
private static _trackCreatedInodes(
|
1161
|
+
container: FileSet,
|
1162
|
+
changed: TestFileSystem,
|
1163
|
+
changedLinks: ReadonlyMap<string, Inode>
|
1164
|
+
) {
|
1165
|
+
// no difference if links are empty
|
1166
|
+
if (!changedLinks.size) {
|
1167
|
+
return false;
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
changedLinks.forEach((node, basename) => {
|
1171
|
+
TestFileSystem._trackCreatedInode(container, basename, changed, node);
|
1172
|
+
});
|
1173
|
+
return true;
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
private static _trackDeletedInodes(container: FileSet, baseLinks: ReadonlyMap<string, Inode>) {
|
1177
|
+
// no difference if links are empty
|
1178
|
+
if (!baseLinks.size) {
|
1179
|
+
return false;
|
1180
|
+
}
|
1181
|
+
baseLinks.forEach((node, basename) => {
|
1182
|
+
container[basename] = isDirectory(node) ? new Rmdir() : new Unlink();
|
1183
|
+
});
|
1184
|
+
return true;
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
private _mknod(dev: number, type: typeof S_IFREG, mode: number, time?: number): FileInode;
|
1188
|
+
private _mknod(dev: number, type: typeof S_IFDIR, mode: number, time?: number): DirectoryInode;
|
1189
|
+
private _mknod(dev: number, type: typeof S_IFLNK, mode: number, time?: number): SymlinkInode;
|
1190
|
+
private _mknod(dev: number, type: number, mode: number, time = this.time()): Inode {
|
1191
|
+
return {
|
1192
|
+
dev,
|
1193
|
+
ino: ++inoCount,
|
1194
|
+
mode: (mode & ~S_IFMT & ~0o022 & 0o7777) | (type & S_IFMT),
|
1195
|
+
atimeMs: time,
|
1196
|
+
mtimeMs: time,
|
1197
|
+
ctimeMs: time,
|
1198
|
+
birthtimeMs: time,
|
1199
|
+
nlink: 0,
|
1200
|
+
};
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
private _addLink(
|
1204
|
+
parent: DirectoryInode | undefined,
|
1205
|
+
links: SortedMap<string, Inode>,
|
1206
|
+
name: string,
|
1207
|
+
node: Inode,
|
1208
|
+
time = this.time()
|
1209
|
+
) {
|
1210
|
+
links.set(name, node);
|
1211
|
+
node.nlink++;
|
1212
|
+
node.ctimeMs = time;
|
1213
|
+
if (parent) {
|
1214
|
+
parent.mtimeMs = time;
|
1215
|
+
}
|
1216
|
+
if (!parent && !this._cwd) {
|
1217
|
+
this._cwd = name;
|
1218
|
+
}
|
1219
|
+
}
|
1220
|
+
|
1221
|
+
private _removeLink(
|
1222
|
+
parent: DirectoryInode | undefined,
|
1223
|
+
links: SortedMap<string, Inode>,
|
1224
|
+
name: string,
|
1225
|
+
node: Inode,
|
1226
|
+
time = this.time()
|
1227
|
+
) {
|
1228
|
+
links.delete(name);
|
1229
|
+
node.nlink--;
|
1230
|
+
node.ctimeMs = time;
|
1231
|
+
if (parent) {
|
1232
|
+
parent.mtimeMs = time;
|
1233
|
+
}
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
private _replaceLink(
|
1237
|
+
oldParent: DirectoryInode,
|
1238
|
+
oldLinks: SortedMap<string, Inode>,
|
1239
|
+
oldName: string,
|
1240
|
+
newParent: DirectoryInode,
|
1241
|
+
newLinks: SortedMap<string, Inode>,
|
1242
|
+
newName: string,
|
1243
|
+
node: Inode,
|
1244
|
+
time: number
|
1245
|
+
) {
|
1246
|
+
if (oldParent !== newParent) {
|
1247
|
+
this._removeLink(oldParent, oldLinks, oldName, node, time);
|
1248
|
+
this._addLink(newParent, newLinks, newName, node, time);
|
1249
|
+
} else {
|
1250
|
+
oldLinks.delete(oldName);
|
1251
|
+
oldLinks.set(newName, node);
|
1252
|
+
oldParent.mtimeMs = time;
|
1253
|
+
newParent.mtimeMs = time;
|
1254
|
+
}
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
private _getRootLinks() {
|
1258
|
+
if (!this._lazy.links) {
|
1259
|
+
const links = new SortedMap<string, Inode>(this.stringComparer);
|
1260
|
+
if (this._shadowRoot) {
|
1261
|
+
this._copyShadowLinks(this._shadowRoot._getRootLinks(), links);
|
1262
|
+
}
|
1263
|
+
this._lazy.links = links;
|
1264
|
+
}
|
1265
|
+
return this._lazy.links;
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
private _getLinks(node: DirectoryInode) {
|
1269
|
+
if (!node.links) {
|
1270
|
+
const links = new SortedMap<string, Inode>(this.stringComparer);
|
1271
|
+
const { source, resolver } = node;
|
1272
|
+
if (source && resolver) {
|
1273
|
+
node.source = undefined;
|
1274
|
+
node.resolver = undefined;
|
1275
|
+
for (const name of resolver.readdirSync(source)) {
|
1276
|
+
const path = pathUtil.combinePaths(source, name);
|
1277
|
+
const stats = resolver.statSync(path);
|
1278
|
+
switch (stats.mode & S_IFMT) {
|
1279
|
+
case S_IFDIR: {
|
1280
|
+
const dir = this._mknod(node.dev, S_IFDIR, 0o777);
|
1281
|
+
dir.source = pathUtil.combinePaths(source, name);
|
1282
|
+
dir.resolver = resolver;
|
1283
|
+
this._addLink(node, links, name, dir);
|
1284
|
+
break;
|
1285
|
+
}
|
1286
|
+
case S_IFREG: {
|
1287
|
+
const file = this._mknod(node.dev, S_IFREG, 0o666);
|
1288
|
+
file.source = pathUtil.combinePaths(source, name);
|
1289
|
+
file.resolver = resolver;
|
1290
|
+
file.size = stats.size;
|
1291
|
+
this._addLink(node, links, name, file);
|
1292
|
+
break;
|
1293
|
+
}
|
1294
|
+
}
|
1295
|
+
}
|
1296
|
+
} else if (this._shadowRoot && node.shadowRoot) {
|
1297
|
+
this._copyShadowLinks(this._shadowRoot._getLinks(node.shadowRoot), links);
|
1298
|
+
}
|
1299
|
+
node.links = links;
|
1300
|
+
}
|
1301
|
+
return node.links;
|
1302
|
+
}
|
1303
|
+
|
1304
|
+
private _getShadow(root: DirectoryInode): DirectoryInode;
|
1305
|
+
private _getShadow(root: Inode): Inode;
|
1306
|
+
private _getShadow(root: Inode) {
|
1307
|
+
const shadows = this._lazy.shadows || (this._lazy.shadows = new Map<number, Inode>());
|
1308
|
+
|
1309
|
+
let shadow = shadows.get(root.ino);
|
1310
|
+
if (!shadow) {
|
1311
|
+
shadow = {
|
1312
|
+
dev: root.dev,
|
1313
|
+
ino: root.ino,
|
1314
|
+
mode: root.mode,
|
1315
|
+
atimeMs: root.atimeMs,
|
1316
|
+
mtimeMs: root.mtimeMs,
|
1317
|
+
ctimeMs: root.ctimeMs,
|
1318
|
+
birthtimeMs: root.birthtimeMs,
|
1319
|
+
nlink: root.nlink,
|
1320
|
+
shadowRoot: root,
|
1321
|
+
};
|
1322
|
+
|
1323
|
+
if (isSymlink(root)) {
|
1324
|
+
(shadow as SymlinkInode).symlink = root.symlink;
|
1325
|
+
}
|
1326
|
+
shadows.set(shadow.ino, shadow);
|
1327
|
+
}
|
1328
|
+
|
1329
|
+
return shadow;
|
1330
|
+
}
|
1331
|
+
|
1332
|
+
private _copyShadowLinks(source: ReadonlyMap<string, Inode>, target: SortedMap<string, Inode>) {
|
1333
|
+
const iterator = getIterator(source);
|
1334
|
+
try {
|
1335
|
+
for (let i = nextResult(iterator); i; i = nextResult(iterator)) {
|
1336
|
+
const [name, root] = i.value;
|
1337
|
+
target.set(name, this._getShadow(root));
|
1338
|
+
}
|
1339
|
+
} finally {
|
1340
|
+
closeIterator(iterator);
|
1341
|
+
}
|
1342
|
+
}
|
1343
|
+
|
1344
|
+
private _getSize(node: FileInode): number {
|
1345
|
+
if (node.buffer) {
|
1346
|
+
return node.buffer.byteLength;
|
1347
|
+
}
|
1348
|
+
if (node.size !== undefined) {
|
1349
|
+
return node.size;
|
1350
|
+
}
|
1351
|
+
if (node.source && node.resolver) {
|
1352
|
+
return (node.size = node.resolver.statSync(node.source).size);
|
1353
|
+
}
|
1354
|
+
if (this._shadowRoot && node.shadowRoot) {
|
1355
|
+
return (node.size = this._shadowRoot._getSize(node.shadowRoot));
|
1356
|
+
}
|
1357
|
+
return 0;
|
1358
|
+
}
|
1359
|
+
|
1360
|
+
private _getBuffer(node: FileInode): Buffer {
|
1361
|
+
if (!node.buffer) {
|
1362
|
+
const { source, resolver } = node;
|
1363
|
+
if (source && resolver) {
|
1364
|
+
node.source = undefined;
|
1365
|
+
node.resolver = undefined;
|
1366
|
+
node.size = undefined;
|
1367
|
+
node.buffer = resolver.readFileSync(source);
|
1368
|
+
} else if (this._shadowRoot && node.shadowRoot) {
|
1369
|
+
node.buffer = this._shadowRoot._getBuffer(node.shadowRoot);
|
1370
|
+
} else {
|
1371
|
+
node.buffer = Buffer.allocUnsafe(0);
|
1372
|
+
}
|
1373
|
+
}
|
1374
|
+
return node.buffer;
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
/**
|
1378
|
+
* Walk a path to its end.
|
1379
|
+
*
|
1380
|
+
* @param path The path to follow.
|
1381
|
+
* @param noFollow A value indicating whether to *not* dereference a symbolic link at the
|
1382
|
+
* end of a path.
|
1383
|
+
*
|
1384
|
+
* @link http://man7.org/linux/man-pages/man7/path_resolution.7.html
|
1385
|
+
*/
|
1386
|
+
private _walk(
|
1387
|
+
path: string,
|
1388
|
+
noFollow?: boolean,
|
1389
|
+
onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => 'retry' | 'throw'
|
1390
|
+
): WalkResult;
|
1391
|
+
private _walk(
|
1392
|
+
path: string,
|
1393
|
+
noFollow?: boolean,
|
1394
|
+
onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => 'stop' | 'retry' | 'throw'
|
1395
|
+
): WalkResult | undefined;
|
1396
|
+
private _walk(
|
1397
|
+
path: string,
|
1398
|
+
noFollow?: boolean,
|
1399
|
+
onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => 'stop' | 'retry' | 'throw'
|
1400
|
+
): WalkResult | undefined {
|
1401
|
+
let links = this._getRootLinks();
|
1402
|
+
let parent: DirectoryInode | undefined;
|
1403
|
+
let components = pathUtil.getPathComponents(path);
|
1404
|
+
let step = 0;
|
1405
|
+
let depth = 0;
|
1406
|
+
let retry = false;
|
1407
|
+
while (true) {
|
1408
|
+
if (depth >= 40) {
|
1409
|
+
throw createIOError('ELOOP');
|
1410
|
+
}
|
1411
|
+
const lastStep = step === components.length - 1;
|
1412
|
+
const basename = components[step];
|
1413
|
+
const node = links.get(basename);
|
1414
|
+
if (lastStep && (noFollow || !isSymlink(node))) {
|
1415
|
+
return { realpath: pathUtil.combinePathComponents(components), basename, parent, links, node };
|
1416
|
+
}
|
1417
|
+
if (node === undefined) {
|
1418
|
+
if (trapError(createIOError('ENOENT'), node)) {
|
1419
|
+
continue;
|
1420
|
+
}
|
1421
|
+
return undefined;
|
1422
|
+
}
|
1423
|
+
if (isSymlink(node)) {
|
1424
|
+
const dirname = pathUtil.combinePathComponents(components.slice(0, step));
|
1425
|
+
const symlink = pathUtil.resolvePaths(dirname, node.symlink);
|
1426
|
+
links = this._getRootLinks();
|
1427
|
+
parent = undefined;
|
1428
|
+
components = pathUtil.getPathComponents(symlink).concat(components.slice(step + 1));
|
1429
|
+
step = 0;
|
1430
|
+
depth++;
|
1431
|
+
retry = false;
|
1432
|
+
continue;
|
1433
|
+
}
|
1434
|
+
if (isDirectory(node)) {
|
1435
|
+
links = this._getLinks(node);
|
1436
|
+
parent = node;
|
1437
|
+
step++;
|
1438
|
+
retry = false;
|
1439
|
+
continue;
|
1440
|
+
}
|
1441
|
+
if (trapError(createIOError('ENOTDIR'), node)) {
|
1442
|
+
continue;
|
1443
|
+
}
|
1444
|
+
return undefined;
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
function trapError(error: NodeJS.ErrnoException, node?: Inode) {
|
1448
|
+
const realpath = pathUtil.combinePathComponents(components.slice(0, step + 1));
|
1449
|
+
const basename = components[step];
|
1450
|
+
const result = !retry && onError ? onError(error, { realpath, basename, parent, links, node }) : 'throw';
|
1451
|
+
if (result === 'stop') {
|
1452
|
+
return false;
|
1453
|
+
}
|
1454
|
+
if (result === 'retry') {
|
1455
|
+
retry = true;
|
1456
|
+
return true;
|
1457
|
+
}
|
1458
|
+
throw error;
|
1459
|
+
}
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
/**
|
1463
|
+
* Resolve a path relative to the current working directory.
|
1464
|
+
*/
|
1465
|
+
private _resolve(path: string) {
|
1466
|
+
return this._cwd
|
1467
|
+
? pathUtil.resolvePaths(
|
1468
|
+
this._cwd,
|
1469
|
+
validate(path, ValidationFlags.RelativeOrAbsolute | ValidationFlags.AllowWildcard)
|
1470
|
+
)
|
1471
|
+
: validate(path, ValidationFlags.Absolute | ValidationFlags.AllowWildcard);
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
private _applyFiles(files: FileSet, dirname: string) {
|
1475
|
+
const deferred: [Symlink | Link | Mount, string][] = [];
|
1476
|
+
this._applyFilesWorker(files, dirname, deferred);
|
1477
|
+
for (const [entry, path] of deferred) {
|
1478
|
+
this.mkdirpSync(pathUtil.getDirectoryPath(path));
|
1479
|
+
this.pushd(pathUtil.getDirectoryPath(path));
|
1480
|
+
if (entry instanceof Symlink) {
|
1481
|
+
if (this.stringComparer(pathUtil.getDirectoryPath(path), path) === 0) {
|
1482
|
+
throw new TypeError('Roots cannot be symbolic links.');
|
1483
|
+
}
|
1484
|
+
this.symlinkSync(pathUtil.resolvePaths(dirname, entry.symlink), path);
|
1485
|
+
this._applyFileExtendedOptions(path, entry);
|
1486
|
+
} else if (entry instanceof Link) {
|
1487
|
+
if (this.stringComparer(pathUtil.getDirectoryPath(path), path) === 0) {
|
1488
|
+
throw new TypeError('Roots cannot be hard links.');
|
1489
|
+
}
|
1490
|
+
this.linkSync(entry.path, path);
|
1491
|
+
} else {
|
1492
|
+
this.mountSync(entry.source, path, entry.resolver);
|
1493
|
+
this._applyFileExtendedOptions(path, entry);
|
1494
|
+
}
|
1495
|
+
this.popd();
|
1496
|
+
}
|
1497
|
+
}
|
1498
|
+
|
1499
|
+
private _applyFileExtendedOptions(path: string, entry: Directory | File | Symlink | Mount) {
|
1500
|
+
const { meta } = entry;
|
1501
|
+
if (meta !== undefined) {
|
1502
|
+
const filemeta = this.filemeta(path);
|
1503
|
+
for (const key of Object.keys(meta)) {
|
1504
|
+
filemeta.set(key, meta[key]);
|
1505
|
+
}
|
1506
|
+
}
|
1507
|
+
}
|
1508
|
+
|
1509
|
+
private _applyFilesWorker(files: FileSet, dirname: string, deferred: [Symlink | Link | Mount, string][]) {
|
1510
|
+
for (const key of Object.keys(files)) {
|
1511
|
+
const value = normalizeFileSetEntry(files[key]);
|
1512
|
+
const path = dirname ? pathUtil.resolvePaths(dirname, key) : key;
|
1513
|
+
validate(path, ValidationFlags.Absolute);
|
1514
|
+
|
1515
|
+
if (value === null || value === undefined || value instanceof Rmdir || value instanceof Unlink) {
|
1516
|
+
if (this.stringComparer(pathUtil.getDirectoryPath(path), path) === 0) {
|
1517
|
+
throw new TypeError('Roots cannot be deleted.');
|
1518
|
+
}
|
1519
|
+
this.rimrafSync(path);
|
1520
|
+
} else if (value instanceof File) {
|
1521
|
+
if (this.stringComparer(pathUtil.getDirectoryPath(path), path) === 0) {
|
1522
|
+
throw new TypeError('Roots cannot be files.');
|
1523
|
+
}
|
1524
|
+
this.mkdirpSync(pathUtil.getDirectoryPath(path));
|
1525
|
+
this.writeFileSync(path, value.data, value.encoding);
|
1526
|
+
this._applyFileExtendedOptions(path, value);
|
1527
|
+
} else if (value instanceof Directory) {
|
1528
|
+
this.mkdirpSync(path);
|
1529
|
+
this._applyFileExtendedOptions(path, value);
|
1530
|
+
this._applyFilesWorker(value.files, path, deferred);
|
1531
|
+
} else {
|
1532
|
+
deferred.push([value, path]);
|
1533
|
+
}
|
1534
|
+
}
|
1535
|
+
}
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
export interface FileSystemOptions {
|
1539
|
+
// Sets the initial timestamp for new files and directories, or the function used
|
1540
|
+
// to calculate timestamps.
|
1541
|
+
time?: number | Date | (() => number | Date) | undefined;
|
1542
|
+
|
1543
|
+
// A set of file system entries to initially add to the file system.
|
1544
|
+
files?: FileSet | undefined;
|
1545
|
+
|
1546
|
+
// Sets the initial working directory for the file system.
|
1547
|
+
cwd?: string | undefined;
|
1548
|
+
|
1549
|
+
// Sets initial metadata attached to the file system.
|
1550
|
+
meta?: Record<string, any> | undefined;
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
export type Axis = 'ancestors' | 'ancestors-or-self' | 'self' | 'descendants-or-self' | 'descendants';
|
1554
|
+
|
1555
|
+
export interface Traversal {
|
1556
|
+
/** A function called to choose whether to continue to traverse to either ancestors or descendants. */
|
1557
|
+
traverse?(path: string, stats: Stats): boolean;
|
1558
|
+
/** A function called to choose whether to accept a path as part of the result. */
|
1559
|
+
accept?(path: string, stats: Stats): boolean;
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
export interface FileSystemResolver {
|
1563
|
+
statSync(path: string): { mode: number; size: number };
|
1564
|
+
readdirSync(path: string): string[];
|
1565
|
+
readFileSync(path: string): Buffer;
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
/**
|
1569
|
+
* A template used to populate files, directories, links, etc. in a virtual file system.
|
1570
|
+
*/
|
1571
|
+
export interface FileSet {
|
1572
|
+
[name: string]: DirectoryLike | FileLike | Link | Symlink | Mount | Rmdir | Unlink | null | undefined;
|
1573
|
+
}
|
1574
|
+
|
1575
|
+
export type DirectoryLike = FileSet | Directory;
|
1576
|
+
export type FileLike = File | Buffer | string;
|
1577
|
+
|
1578
|
+
/** Extended options for a directory in a `FileSet` */
|
1579
|
+
export class Directory {
|
1580
|
+
readonly files: FileSet;
|
1581
|
+
readonly meta: Record<string, any> | undefined;
|
1582
|
+
constructor(files: FileSet, { meta }: { meta?: Record<string, any> } = {}) {
|
1583
|
+
this.files = files;
|
1584
|
+
this.meta = meta;
|
1585
|
+
}
|
1586
|
+
}
|
1587
|
+
|
1588
|
+
/** Extended options for a file in a `FileSet` */
|
1589
|
+
export class File {
|
1590
|
+
readonly data: Buffer | string;
|
1591
|
+
readonly encoding: BufferEncoding | undefined;
|
1592
|
+
readonly meta: Record<string, any> | undefined;
|
1593
|
+
constructor(
|
1594
|
+
data: Buffer | string,
|
1595
|
+
{ meta, encoding }: { encoding?: BufferEncoding; meta?: Record<string, any> } = {}
|
1596
|
+
) {
|
1597
|
+
this.data = data;
|
1598
|
+
this.encoding = encoding;
|
1599
|
+
this.meta = meta;
|
1600
|
+
}
|
1601
|
+
}
|
1602
|
+
|
1603
|
+
export class SameFileContentFile extends File {
|
1604
|
+
constructor(data: Buffer | string, metaAndEncoding?: { encoding?: BufferEncoding; meta?: Record<string, any> }) {
|
1605
|
+
super(data, metaAndEncoding);
|
1606
|
+
}
|
1607
|
+
}
|
1608
|
+
|
1609
|
+
/** Extended options for a hard link in a `FileSet` */
|
1610
|
+
export class Link {
|
1611
|
+
readonly path: string;
|
1612
|
+
constructor(path: string) {
|
1613
|
+
this.path = path;
|
1614
|
+
}
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
/** Removes a directory in a `FileSet` */
|
1618
|
+
export class Rmdir {
|
1619
|
+
' rmdirBrand'?: never; // brand necessary for proper type guards
|
1620
|
+
}
|
1621
|
+
|
1622
|
+
/** Unlinks a file in a `FileSet` */
|
1623
|
+
export class Unlink {
|
1624
|
+
' unlinkBrand'?: never; // brand necessary for proper type guards
|
1625
|
+
}
|
1626
|
+
|
1627
|
+
/** Extended options for a symbolic link in a `FileSet` */
|
1628
|
+
export class Symlink {
|
1629
|
+
readonly symlink: string;
|
1630
|
+
readonly meta: Record<string, any> | undefined;
|
1631
|
+
constructor(symlink: string, { meta }: { meta?: Record<string, any> } = {}) {
|
1632
|
+
this.symlink = symlink;
|
1633
|
+
this.meta = meta;
|
1634
|
+
}
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
// file type
|
1638
|
+
// these should be only used inside of test code. it is export just because mock file system is separated into
|
1639
|
+
// 2 files. this and factory.ts file. actual value doesn't matter
|
1640
|
+
export const S_IFMT = 0o170000; // file type
|
1641
|
+
export const S_IFSOCK = 0o140000; // socket
|
1642
|
+
export const S_IFLNK = 0o120000; // symbolic link
|
1643
|
+
export const S_IFREG = 0o100000; // regular file
|
1644
|
+
export const S_IFBLK = 0o060000; // block device
|
1645
|
+
export const S_IFDIR = 0o040000; // directory
|
1646
|
+
export const S_IFCHR = 0o020000; // character device
|
1647
|
+
export const S_IFIFO = 0o010000; // FIFO
|
1648
|
+
|
1649
|
+
/** Extended options for mounting a virtual copy of an external file system via a `FileSet` */
|
1650
|
+
export class Mount {
|
1651
|
+
readonly source: string;
|
1652
|
+
readonly resolver: FileSystemResolver;
|
1653
|
+
readonly meta: Record<string, any> | undefined;
|
1654
|
+
constructor(source: string, resolver: FileSystemResolver, { meta }: { meta?: Record<string, any> } = {}) {
|
1655
|
+
this.source = source;
|
1656
|
+
this.resolver = resolver;
|
1657
|
+
this.meta = meta;
|
1658
|
+
}
|
1659
|
+
}
|
1660
|
+
|
1661
|
+
// a generic POSIX inode
|
1662
|
+
type Inode = FileInode | DirectoryInode | SymlinkInode;
|
1663
|
+
|
1664
|
+
interface FileInode {
|
1665
|
+
dev: number; // device id
|
1666
|
+
ino: number; // inode id
|
1667
|
+
mode: number; // file mode
|
1668
|
+
atimeMs: number; // access time
|
1669
|
+
mtimeMs: number; // modified time
|
1670
|
+
ctimeMs: number; // status change time
|
1671
|
+
birthtimeMs: number; // creation time
|
1672
|
+
nlink: number; // number of hard links
|
1673
|
+
size?: number | undefined;
|
1674
|
+
buffer?: Buffer | undefined;
|
1675
|
+
source?: string | undefined;
|
1676
|
+
resolver?: FileSystemResolver | undefined;
|
1677
|
+
shadowRoot?: FileInode | undefined;
|
1678
|
+
meta?: Metadata | undefined;
|
1679
|
+
}
|
1680
|
+
|
1681
|
+
interface DirectoryInode {
|
1682
|
+
dev: number; // device id
|
1683
|
+
ino: number; // inode id
|
1684
|
+
mode: number; // file mode
|
1685
|
+
atimeMs: number; // access time
|
1686
|
+
mtimeMs: number; // modified time
|
1687
|
+
ctimeMs: number; // status change time
|
1688
|
+
birthtimeMs: number; // creation time
|
1689
|
+
nlink: number; // number of hard links
|
1690
|
+
links?: SortedMap<string, Inode> | undefined;
|
1691
|
+
source?: string | undefined;
|
1692
|
+
resolver?: FileSystemResolver | undefined;
|
1693
|
+
shadowRoot?: DirectoryInode | undefined;
|
1694
|
+
meta?: Metadata | undefined;
|
1695
|
+
}
|
1696
|
+
|
1697
|
+
interface SymlinkInode {
|
1698
|
+
dev: number; // device id
|
1699
|
+
ino: number; // inode id
|
1700
|
+
mode: number; // file mode
|
1701
|
+
atimeMs: number; // access time
|
1702
|
+
mtimeMs: number; // modified time
|
1703
|
+
ctimeMs: number; // status change time
|
1704
|
+
birthtimeMs: number; // creation time
|
1705
|
+
nlink: number; // number of hard links
|
1706
|
+
symlink: string;
|
1707
|
+
shadowRoot?: SymlinkInode | undefined;
|
1708
|
+
meta?: Metadata | undefined;
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
function isEmptyNonShadowedDirectory(node: DirectoryInode) {
|
1712
|
+
return !node.links && !node.shadowRoot && !node.resolver && !node.source;
|
1713
|
+
}
|
1714
|
+
|
1715
|
+
function isEmptyNonShadowedFile(node: FileInode) {
|
1716
|
+
return !node.buffer && !node.shadowRoot && !node.resolver && !node.source;
|
1717
|
+
}
|
1718
|
+
|
1719
|
+
function isFile(node: Inode | undefined): node is FileInode {
|
1720
|
+
return node !== undefined && (node.mode & S_IFMT) === S_IFREG;
|
1721
|
+
}
|
1722
|
+
|
1723
|
+
function isDirectory(node: Inode | undefined): node is DirectoryInode {
|
1724
|
+
return node !== undefined && (node.mode & S_IFMT) === S_IFDIR;
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
function isSymlink(node: Inode | undefined): node is SymlinkInode {
|
1728
|
+
return node !== undefined && (node.mode & S_IFMT) === S_IFLNK;
|
1729
|
+
}
|
1730
|
+
|
1731
|
+
interface WalkResult {
|
1732
|
+
realpath: string;
|
1733
|
+
basename: string;
|
1734
|
+
parent: DirectoryInode | undefined;
|
1735
|
+
links: SortedMap<string, Inode>;
|
1736
|
+
node: Inode | undefined;
|
1737
|
+
}
|
1738
|
+
|
1739
|
+
function normalizeFileSetEntry(value: FileSet[string]) {
|
1740
|
+
if (
|
1741
|
+
value === undefined ||
|
1742
|
+
value === null ||
|
1743
|
+
value instanceof Directory ||
|
1744
|
+
value instanceof File ||
|
1745
|
+
value instanceof Link ||
|
1746
|
+
value instanceof Symlink ||
|
1747
|
+
value instanceof Mount ||
|
1748
|
+
value instanceof Rmdir ||
|
1749
|
+
value instanceof Unlink
|
1750
|
+
) {
|
1751
|
+
return value;
|
1752
|
+
}
|
1753
|
+
return typeof value === 'string' || Buffer.isBuffer(value) ? new File(value) : new Directory(value);
|
1754
|
+
}
|
1755
|
+
|
1756
|
+
export function formatPatch(patch: FileSet): string;
|
1757
|
+
export function formatPatch(patch: FileSet | undefined): string | null;
|
1758
|
+
export function formatPatch(patch: FileSet | undefined) {
|
1759
|
+
return patch ? formatPatchWorker('', patch) : null;
|
1760
|
+
}
|
1761
|
+
|
1762
|
+
function formatPatchWorker(dirname: string, container: FileSet): string {
|
1763
|
+
let text = '';
|
1764
|
+
for (const name of Object.keys(container)) {
|
1765
|
+
const entry = normalizeFileSetEntry(container[name]);
|
1766
|
+
const file = dirname ? pathUtil.combinePaths(dirname, name) : name;
|
1767
|
+
if (entry === null || entry === undefined || entry instanceof Unlink) {
|
1768
|
+
text += `//// [${file}] unlink\r\n`;
|
1769
|
+
} else if (entry instanceof Rmdir) {
|
1770
|
+
text += `//// [${pathUtil.ensureTrailingDirectorySeparator(file)}] rmdir\r\n`;
|
1771
|
+
} else if (entry instanceof Directory) {
|
1772
|
+
text += formatPatchWorker(file, entry.files);
|
1773
|
+
} else if (entry instanceof SameFileContentFile) {
|
1774
|
+
text += `//// [${file}] file written with same contents\r\n`;
|
1775
|
+
} else if (entry instanceof File) {
|
1776
|
+
const content = typeof entry.data === 'string' ? entry.data : entry.data.toString('utf8');
|
1777
|
+
text += `//// [${file}]\r\n${content}\r\n\r\n`;
|
1778
|
+
} else if (entry instanceof Link) {
|
1779
|
+
text += `//// [${file}] link(${entry.path})\r\n`;
|
1780
|
+
} else if (entry instanceof Symlink) {
|
1781
|
+
text += `//// [${file}] symlink(${entry.symlink})\r\n`;
|
1782
|
+
} else if (entry instanceof Mount) {
|
1783
|
+
text += `//// [${file}] mount(${entry.source})\r\n`;
|
1784
|
+
}
|
1785
|
+
}
|
1786
|
+
return text;
|
1787
|
+
}
|
1788
|
+
|
1789
|
+
function makeDirEnt(name: string, node: Inode): Dirent {
|
1790
|
+
const de: Dirent = {
|
1791
|
+
isFile: () => isFile(node),
|
1792
|
+
isDirectory: () => isDirectory(node),
|
1793
|
+
isBlockDevice: () => false,
|
1794
|
+
isCharacterDevice: () => false,
|
1795
|
+
isFIFO: () => false,
|
1796
|
+
isSocket: () => false,
|
1797
|
+
isSymbolicLink: () => isSymlink(node),
|
1798
|
+
name,
|
1799
|
+
};
|
1800
|
+
return de;
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
class Stats {
|
1804
|
+
dev: number;
|
1805
|
+
ino: number;
|
1806
|
+
mode: number;
|
1807
|
+
nlink: number;
|
1808
|
+
uid: number;
|
1809
|
+
gid: number;
|
1810
|
+
rdev: number;
|
1811
|
+
size: number;
|
1812
|
+
blksize: number;
|
1813
|
+
blocks: number;
|
1814
|
+
atimeMs: number;
|
1815
|
+
mtimeMs: number;
|
1816
|
+
ctimeMs: number;
|
1817
|
+
birthtimeMs: number;
|
1818
|
+
atime: Date;
|
1819
|
+
mtime: Date;
|
1820
|
+
ctime: Date;
|
1821
|
+
birthtime: Date;
|
1822
|
+
|
1823
|
+
constructor();
|
1824
|
+
constructor(
|
1825
|
+
dev: number,
|
1826
|
+
ino: number,
|
1827
|
+
mode: number,
|
1828
|
+
nlink: number,
|
1829
|
+
rdev: number,
|
1830
|
+
size: number,
|
1831
|
+
blksize: number,
|
1832
|
+
blocks: number,
|
1833
|
+
atimeMs: number,
|
1834
|
+
mtimeMs: number,
|
1835
|
+
ctimeMs: number,
|
1836
|
+
birthtimeMs: number
|
1837
|
+
);
|
1838
|
+
constructor(
|
1839
|
+
dev = 0,
|
1840
|
+
ino = 0,
|
1841
|
+
mode = 0,
|
1842
|
+
nlink = 0,
|
1843
|
+
rdev = 0,
|
1844
|
+
size = 0,
|
1845
|
+
blksize = 0,
|
1846
|
+
blocks = 0,
|
1847
|
+
atimeMs = 0,
|
1848
|
+
mtimeMs = 0,
|
1849
|
+
ctimeMs = 0,
|
1850
|
+
birthtimeMs = 0
|
1851
|
+
) {
|
1852
|
+
this.dev = dev;
|
1853
|
+
this.ino = ino;
|
1854
|
+
this.mode = mode;
|
1855
|
+
this.nlink = nlink;
|
1856
|
+
this.uid = 0;
|
1857
|
+
this.gid = 0;
|
1858
|
+
this.rdev = rdev;
|
1859
|
+
this.size = size;
|
1860
|
+
this.blksize = blksize;
|
1861
|
+
this.blocks = blocks;
|
1862
|
+
this.atimeMs = atimeMs;
|
1863
|
+
this.mtimeMs = mtimeMs;
|
1864
|
+
this.ctimeMs = ctimeMs;
|
1865
|
+
this.birthtimeMs = birthtimeMs;
|
1866
|
+
this.atime = new Date(this.atimeMs);
|
1867
|
+
this.mtime = new Date(this.mtimeMs);
|
1868
|
+
this.ctime = new Date(this.ctimeMs);
|
1869
|
+
this.birthtime = new Date(this.birthtimeMs);
|
1870
|
+
}
|
1871
|
+
|
1872
|
+
isFile() {
|
1873
|
+
return (this.mode & S_IFMT) === S_IFREG;
|
1874
|
+
}
|
1875
|
+
isDirectory() {
|
1876
|
+
return (this.mode & S_IFMT) === S_IFDIR;
|
1877
|
+
}
|
1878
|
+
isSymbolicLink() {
|
1879
|
+
return (this.mode & S_IFMT) === S_IFLNK;
|
1880
|
+
}
|
1881
|
+
isBlockDevice() {
|
1882
|
+
return (this.mode & S_IFMT) === S_IFBLK;
|
1883
|
+
}
|
1884
|
+
isCharacterDevice() {
|
1885
|
+
return (this.mode & S_IFMT) === S_IFCHR;
|
1886
|
+
}
|
1887
|
+
isFIFO() {
|
1888
|
+
return (this.mode & S_IFMT) === S_IFIFO;
|
1889
|
+
}
|
1890
|
+
isSocket() {
|
1891
|
+
return (this.mode & S_IFMT) === S_IFSOCK;
|
1892
|
+
}
|
1893
|
+
}
|