├── .drone.yml.sig ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── ci.yml │ ├── release-drafter.yml │ ├── release-native.yml │ └── release.yml ├── .gitignore ├── .jvmopts ├── .scala-steward.conf ├── .scalafmt.conf ├── CONTRIBUTING.md ├── Dockerfile ├── LICENCE.md ├── appveyor.yml ├── bin ├── _scalafmt ├── build-native-image.sh ├── configure ├── install-scalafmt-native.sh ├── repo-commits.sh ├── run-benchmarks.sh ├── scalafmt.bats ├── scalafmt_ng └── test-release.sh ├── build.sbt ├── docs ├── CHANGELOG.md ├── assets │ └── img │ │ ├── intellij-choose-formatter.png │ │ ├── intellij-install.png │ │ ├── intellij-on-save-native.png │ │ ├── intellij-on-save.png │ │ └── intellij-plugin.png ├── configuration.md ├── contributing-scalafmt.md ├── contributing-website.md ├── faq.md ├── gotchas.md ├── installation.md ├── introduction.md └── known-issues.md ├── download_scalafmt ├── package.json ├── project ├── Dependencies.scala ├── Mima.scala ├── build.properties └── plugins.sbt ├── readme.md ├── readme ├── Intro ├── Matrix.example ├── resources │ ├── custom.css │ ├── custom.js │ ├── favicon.png │ ├── google61cac7acd6a4fdc9.html │ └── img │ │ ├── downloads-201703.png │ │ └── downloads-intellij-201703.png ├── src │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── readme │ │ ├── Adopters.scala │ │ └── Readme.scala └── stripMargin.example ├── scalafmt ├── scalafmt-benchmarks └── src │ ├── main │ ├── scala-2.12 │ │ └── benchmarks │ │ │ └── MacroBenchmark.scala │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── benchmarks │ │ ├── FormatBenchmark.scala │ │ └── MicroBenchmark.scala │ ├── resources │ ├── Endpoint.scala │ ├── scala-js │ │ ├── Analyzer.scala │ │ ├── BaseLinker.scala │ │ ├── CopyOnWriteArrayList.scala │ │ ├── Division.scala │ │ ├── EventSerializers.scala │ │ ├── GenJSCode.scala │ │ ├── JSDependency.scala │ │ ├── JavaLangString.scala │ │ ├── LICENSE │ │ ├── OptimizerCore.scala │ │ ├── Primality.scala │ │ ├── PrintStreamTest.scala │ │ ├── ScalaJSClassEmitter.scala │ │ ├── Semantics.scala │ │ ├── SourceMapWriter.scala │ │ ├── Trees.scala │ │ ├── TypeKinds.scala │ │ ├── Utils.scala │ │ └── readme.md │ ├── scalafmt │ │ └── Basic.scala │ └── spark │ │ └── HiveMetastoreCatalog.scala │ └── test │ └── scala-2.12 │ └── org │ └── scalafmt │ └── benchmarks │ └── BenchmarkOK.scala ├── scalafmt-cli ├── js │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── cli │ │ ├── CliOptionsUtils.scala │ │ ├── CliUtils.scala │ │ ├── PlatformPollingScheduler.scala │ │ └── TermUtils.scala ├── jvm-native │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── cli │ │ └── PlatformPollingScheduler.scala ├── jvm │ └── src │ │ ├── main │ │ └── scala │ │ │ └── org │ │ │ └── scalafmt │ │ │ └── cli │ │ │ ├── CliOptionsUtils.scala │ │ │ ├── CliUtils.scala │ │ │ ├── ScalafmtDynamicRunner.scala │ │ │ └── TermUtils.scala │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── cli │ │ └── CliOptionsJVMTest.scala ├── native │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── cli │ │ ├── CliOptionsUtils.scala │ │ ├── CliUtils.scala │ │ └── TermUtils.scala └── shared │ └── src │ ├── main │ ├── resources │ │ └── META-INF │ │ │ └── native-image │ │ │ └── org.scalafmt │ │ │ └── scalafmt-cli │ │ │ ├── native-image.properties │ │ │ └── reflection.json │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── cli │ │ ├── Cli.scala │ │ ├── CliArgParser.scala │ │ ├── CliOptions.scala │ │ ├── ExitCode.scala │ │ ├── FileFetchMode.scala │ │ ├── InputMethod.scala │ │ ├── Output.scala │ │ ├── PollingScheduler.scala │ │ ├── ScalafmtCliReporter.scala │ │ ├── ScalafmtCoreRunner.scala │ │ ├── ScalafmtRunner.scala │ │ ├── TermDisplay.scala │ │ └── WriteMode.scala │ └── test │ └── scala │ └── org │ └── scalafmt │ └── cli │ ├── CliOptionsTest.scala │ ├── CliTest.scala │ ├── FakeGitOps.scala │ └── FileTestOps.scala ├── scalafmt-config ├── js │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── config │ │ └── PlatformConfig.scala ├── jvm │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── config │ │ └── PlatformConfig.scala ├── native │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── config │ │ └── PlatformConfig.scala └── shared │ └── src │ └── main │ └── scala │ └── org │ └── scalafmt │ └── config │ └── ConfParsed.scala ├── scalafmt-core ├── js │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ ├── config │ │ └── Platform.config │ │ └── internal │ │ └── RegexCompat.scala ├── jvm │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── internal │ │ ├── PriorityQueue.scala │ │ └── RegexCompat.scala ├── native │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── internal │ │ └── RegexCompat.scala └── shared │ └── src │ └── main │ ├── scala-2.12 │ └── scala │ │ └── collection │ │ └── mutable │ │ └── package.scala │ └── scala │ └── org │ └── scalafmt │ ├── Error.scala │ ├── Formatted.scala │ ├── Scalafmt.scala │ ├── config │ ├── Align.scala │ ├── AlignToken.scala │ ├── AvoidInfixSettings.scala │ ├── BinPack.scala │ ├── Comments.scala │ ├── Config.scala │ ├── DanglingParentheses.scala │ ├── Docstrings.scala │ ├── FilterMatcher.scala │ ├── FormatEvent.scala │ ├── ImportSelectors.scala │ ├── IndentOperator.scala │ ├── Indents.scala │ ├── LineEndings.scala │ ├── Literals.scala │ ├── NamedDialect.scala │ ├── Newlines.scala │ ├── Presets.scala │ ├── ProjectFiles.scala │ ├── ReaderUtil.scala │ ├── RedundantBracesSettings.scala │ ├── RedundantParensSettings.scala │ ├── ReflectOps.scala │ ├── RewriteScala3Settings.scala │ ├── RewriteSettings.scala │ ├── RunnerSettings.scala │ ├── ScalafmtConfDecoders.scala │ ├── ScalafmtConfig.scala │ ├── ScalafmtConfigException.scala │ ├── ScalafmtOptimizer.scala │ ├── ScalafmtParser.scala │ ├── SortSettings.scala │ ├── Spaces.scala │ ├── TrailingCommas.scala │ ├── VerticalMultiline.scala │ ├── XmlLiterals.scala │ └── package.scala │ ├── internal │ ├── BestFirstSearch.scala │ ├── Constants.scala │ ├── Decision.scala │ ├── FileLineStack.scala │ ├── FormatOps.scala │ ├── FormatToken.scala │ ├── FormatTokens.scala │ ├── FormatWriter.scala │ ├── Indent.scala │ ├── ModExt.scala │ ├── Modification.scala │ ├── OptimizationEntities.scala │ ├── Policy.scala │ ├── PolicySummary.scala │ ├── Router.scala │ ├── Side.scala │ ├── Split.scala │ ├── SplitTag.scala │ ├── Splits.scala │ ├── SplitsBuilder.scala │ ├── State.scala │ ├── SyntacticGroup.scala │ ├── SyntacticGroupOps.scala │ ├── TokenRange.scala │ ├── TreeSyntacticGroup.scala │ └── package.scala │ ├── rewrite │ ├── AvoidInfix.scala │ ├── ConvertToNewScala3Syntax.scala │ ├── FormatTokensRewrite.scala │ ├── Imports.scala │ ├── PreferCurlyFors.scala │ ├── RedundantBraces.scala │ ├── RedundantParens.scala │ ├── RemoveEmptyDocstrings.scala │ ├── RemoveScala3OptionalBraces.scala │ ├── Rewrite.scala │ ├── RewriteTrailingCommas.scala │ ├── SortModifiers.scala │ └── TokenPatch.scala │ └── util │ ├── LiteralOps.scala │ ├── LogLevel.scala │ ├── LoggerOps.scala │ ├── MarkdownParser.scala │ ├── PolicyOps.scala │ ├── StyleMap.scala │ ├── TokenClasses.scala │ ├── TokenOps.scala │ ├── TokenTraverser.scala │ ├── TreeExtractors.scala │ ├── TreeOps.scala │ └── ValidationOps.scala ├── scalafmt-docs └── src │ └── main │ ├── resources │ └── logback.xml │ └── scala │ ├── docs │ ├── DefaultsModifier.scala │ ├── Docusaurus.scala │ ├── FileModifier.scala │ ├── Main.scala │ └── ScalafmtModifier.scala │ └── website │ └── package.scala ├── scalafmt-dynamic ├── jvm │ └── src │ │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.scalafmt.interfaces.Scalafmt │ │ └── scala │ │ │ └── org │ │ │ └── scalafmt │ │ │ └── dynamic │ │ │ ├── ConsoleScalafmtReporter.scala │ │ │ ├── CoursierDependencyDownloader.scala │ │ │ ├── Dependency.scala │ │ │ ├── DependencyDownloader.scala │ │ │ ├── ScalafmtConfigLoader.scala │ │ │ ├── ScalafmtDynamic.scala │ │ │ ├── ScalafmtDynamicSession.scala │ │ │ ├── ScalafmtModuleLoader.scala │ │ │ ├── ScalafmtProperties.scala │ │ │ ├── ScalafmtReflect.scala │ │ │ ├── ScalafmtReflectConfig.scala │ │ │ ├── exceptions │ │ │ ├── PositionExceptionImpl.scala │ │ │ ├── RangePosition.scala │ │ │ ├── ReflectionException.scala │ │ │ └── VersionMismatch.scala │ │ │ ├── package.scala │ │ │ └── utils │ │ │ ├── ReentrantCache.scala │ │ │ └── ReflectUtils.scala │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── dynamic │ │ ├── DynamicSuite.scala │ │ ├── PositionSyntax.scala │ │ └── ScalafmtVersionSuite.scala ├── native │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── dynamic │ │ └── DynamicSuite.scala └── shared │ └── src │ └── main │ └── scala │ └── org │ └── scalafmt │ └── dynamic │ ├── ScalafmtDynamicError.scala │ ├── ScalafmtVersion.scala │ └── exceptions │ └── ScalafmtException.scala ├── scalafmt-interfaces ├── js │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── interfaces │ │ ├── PositionException.scala │ │ ├── RepositoryCredential.scala │ │ ├── Scalafmt.scala │ │ ├── ScalafmtClassLoader.scala │ │ ├── ScalafmtException.scala │ │ ├── ScalafmtReporter.scala │ │ ├── ScalafmtResult.scala │ │ ├── ScalafmtSession.scala │ │ └── ScalafmtSessionFactory.scala ├── jvm │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── scalafmt │ │ └── interfaces │ │ ├── PositionException.java │ │ ├── RepositoryCredential.java │ │ ├── Scalafmt.java │ │ ├── ScalafmtClassLoader.java │ │ ├── ScalafmtException.java │ │ ├── ScalafmtReporter.java │ │ ├── ScalafmtResult.java │ │ ├── ScalafmtSession.java │ │ └── ScalafmtSessionFactory.java └── native │ └── src │ └── main │ └── java │ └── org │ └── scalafmt │ └── interfaces │ ├── PositionException.scala │ ├── RepositoryCredential.scala │ ├── Scalafmt.scala │ ├── ScalafmtClassLoader.scala │ ├── ScalafmtException.scala │ ├── ScalafmtReporter.scala │ ├── ScalafmtResult.scala │ ├── ScalafmtSession.scala │ └── ScalafmtSessionFactory.scala ├── scalafmt-macros └── shared │ └── src │ └── main │ └── scala │ └── org │ └── scalafmt │ └── config │ └── DialectMacro.scala ├── scalafmt-sysops ├── js │ └── src │ │ ├── main │ │ ├── scala-2.13 │ │ │ └── org │ │ │ │ └── scalafmt │ │ │ │ └── CollectionConverters.scala │ │ └── scala │ │ │ └── org │ │ │ └── scalafmt │ │ │ └── sysops │ │ │ ├── PlatformCompat.scala │ │ │ ├── PlatformFileOps.scala │ │ │ ├── PlatformPathMatcher.scala │ │ │ └── PlatformRunOps.scala │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── sysops │ │ └── DeleteTree.scala ├── jvm-native │ └── src │ │ ├── main │ │ └── scala │ │ │ └── org │ │ │ └── scalafmt │ │ │ └── sysops │ │ │ ├── PlatformFileOps.scala │ │ │ ├── PlatformPathMatcher.scala │ │ │ └── PlatformRunOps.scala │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── sysops │ │ └── DeleteTree.scala ├── jvm │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── sysops │ │ ├── GranularPlatformAsyncOps.scala │ │ └── PlatformCompat.scala ├── native │ └── src │ │ └── main │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── sysops │ │ ├── GranularPlatformAsyncOps.scala │ │ └── PlatformCompat.scala └── shared │ └── src │ ├── main │ ├── scala-2.12 │ │ └── org │ │ │ └── scalafmt │ │ │ ├── CompatCollections.scala │ │ │ └── sysops │ │ │ └── GranularDialectAsyncOps.scala │ ├── scala-2.13 │ │ └── org │ │ │ └── scalafmt │ │ │ ├── CompatCollections.scala │ │ │ └── sysops │ │ │ └── GranularDialectAsyncOps.scala │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── sysops │ │ ├── AbsoluteFile.scala │ │ ├── BatchPathFinder.scala │ │ ├── FileOps.scala │ │ ├── FileStat.scala │ │ ├── GitOps.scala │ │ ├── OsSpecific.scala │ │ ├── PathMatcher.scala │ │ └── ScalafmtSysException.scala │ └── test │ └── scala │ └── org │ └── scalafmt │ └── sysops │ ├── FileOpsTest.scala │ └── GitOpsTest.scala ├── scalafmt-tests-community ├── common │ └── shared │ │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── community │ │ └── common │ │ ├── CommunityBuild.scala │ │ ├── CommunityRepoSuite.scala │ │ ├── CommunitySuite.scala │ │ ├── TestHelpers.scala │ │ ├── TestStats.scala │ │ └── TestStyles.scala ├── intellij │ └── shared │ │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── community │ │ └── intellij │ │ └── CommunityIntellijScalaSuite.scala ├── other │ └── shared │ │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── community │ │ └── other │ │ ├── CommunityAkkaSuite.scala │ │ ├── CommunityMunitSuite.scala │ │ ├── CommunityPlayFrameworkSuite.scala │ │ ├── CommunityScalaCliSuite.scala │ │ ├── CommunityScalaJsSuite.scala │ │ ├── CommunityScalazSuite.scala │ │ └── CommunityZioSuite.scala ├── scala2 │ └── shared │ │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── community │ │ └── scala2 │ │ └── CommunityScala2Suite.scala ├── scala3 │ └── shared │ │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── community │ │ └── scala3 │ │ └── CommunityScala3Suite.scala └── spark │ └── shared │ └── src │ └── test │ └── scala │ └── org │ └── scalafmt │ └── community │ └── spark │ └── CommunitySparkSuite.scala ├── scalafmt-tests ├── js │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── TestPlatformCompat.scala ├── jvm │ └── src │ │ └── test │ │ ├── scala-2.12 │ │ └── org.scalafmt │ │ │ └── TestCompatCollections.scala │ │ ├── scala-2.13 │ │ └── org │ │ │ └── scalafmt │ │ │ └── TestCompatCollections.scala │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ ├── ScalafmtProps.scala │ │ └── TestPlatformCompat.scala ├── native │ └── src │ │ └── test │ │ └── scala │ │ └── org │ │ └── scalafmt │ │ └── TestPlatformCompat.scala └── shared │ └── src │ └── test │ ├── resources │ ├── Test.manual │ ├── align │ │ ├── AlignByRightName.stat │ │ ├── ArrowEnumeratorGenerator.stat │ │ ├── BeforeCommentWithinMethodChain.stat │ │ ├── DefaultWithAlign.stat │ │ ├── MixedTokens.stat │ │ ├── NoSpace.stat │ │ ├── TrollAlignment.stat │ │ ├── addSbtPlugin.source │ │ ├── comment-wrapping.source │ │ ├── defaultTokenOwners.stat │ │ └── duplicateAlign.stat │ ├── binPack │ │ ├── LambdaParameterFalse.stat │ │ ├── LiteralList.stat │ │ ├── LiteralListNoByte.stat │ │ ├── ParentConstructors.stat │ │ └── TermNameList.stat │ ├── default │ │ ├── Advanced.stat │ │ ├── Apply.stat │ │ ├── ApplyInfix.stat │ │ ├── Case.case │ │ ├── Case.stat │ │ ├── Class.stat │ │ ├── Comment.stat │ │ ├── DefDef.stat │ │ ├── Fidelity.source │ │ ├── Fidelity.stat │ │ ├── For.stat │ │ ├── Idempotency.stat │ │ ├── If.stat │ │ ├── Lambda.stat │ │ ├── SearchState.stat │ │ ├── Select.stat │ │ ├── Semicolon.stat │ │ ├── String.stat │ │ ├── Super.stat │ │ ├── TermParam.stat │ │ ├── TestingClassNameDoNotEdit.scalafmt │ │ ├── Trait.stat │ │ ├── Try.stat │ │ ├── TypeArguments.stat │ │ ├── TypeWith.stat │ │ ├── Unicode.stat │ │ ├── Unindent.stat │ │ └── Val.stat │ ├── literals │ │ ├── Double.stat │ │ ├── Float.stat │ │ ├── Long.stat │ │ ├── Unchanged.stat │ │ ├── binary.stat │ │ ├── hex.stat │ │ └── scientific.stat │ ├── newdefault │ │ ├── CaseNoAlign.stat │ │ ├── ColumnWidth.stat │ │ └── SearchState.stat │ ├── newlines │ │ ├── AlwaysBeforeCurlyBraceLambdaParams.stat │ │ ├── OffByOneParameterlessMethod.stat │ │ ├── afterCurlyLambdaAlways.stat │ │ ├── afterCurlyLambdaNever.stat │ │ ├── afterCurlyLambdaPreserve.stat │ │ ├── afterCurlyLambdaSquash.stat │ │ ├── alwaysBeforeElseAfterCurlyIf.stat │ │ ├── alwaysBeforeMultilineDef.stat │ │ ├── alwaysBeforeTopLevelStatements.source │ │ ├── alwaysBeforeTopLevelStatements.stat │ │ ├── beforeConfigSingleArgParenLambdaParamsF_danglingF.stat │ │ ├── beforeConfigSingleArgParenLambdaParamsF_danglingT.stat │ │ ├── newlineBetweenCurlyAndCatchFinally.stat │ │ ├── source.source │ │ ├── source_classic.stat │ │ ├── source_fold.stat │ │ ├── source_keep.stat │ │ └── source_unfold.stat │ ├── optIn │ │ ├── Annotation.stat │ │ ├── AnnotationParam.stat │ │ ├── BreakChainOnFirstMethodDot.stat │ │ ├── SelectChain.stat │ │ ├── SelectChains.stat │ │ ├── SelfAnnotation.stat │ │ └── forceBlankLineBeforeDocstring.stat │ ├── readme.md │ ├── rewrite │ │ ├── AsciiSortImports.stat │ │ ├── AvoidInfix.stat │ │ ├── AvoidInfix2.stat │ │ ├── AvoidInfix3.stat │ │ ├── ExpandImportSelectors.stat │ │ ├── Imports.source │ │ ├── PreferCurlyForYields.stat │ │ ├── PreferCurlyFors.stat │ │ ├── RedundantBraces-ParenLambdas.stat │ │ ├── RedundantBraces-case.stat │ │ ├── RedundantBraces-if.stat │ │ ├── RedundantBraces-precedence.stat │ │ ├── RedundantBraces.stat │ │ ├── RedundantBraces2.stat │ │ ├── RedundantBraces748.stat │ │ ├── RedundantBracesStrInterpolation.stat │ │ ├── RedundantParens.stat │ │ ├── SortImports.stat │ │ ├── SortModifiers.stat │ │ ├── SortModifiers1.source │ │ ├── SortModifiersScala3.stat │ │ ├── SortModifiers_Default.source │ │ ├── SortModifiers_Mod_With_No_Token.source │ │ ├── SortModifiers_bug_1148.stat │ │ └── SortModifiers_bug_1148_implicit_first_in_order.stat │ ├── scala3 │ │ ├── ContextFunction.stat │ │ ├── DependentFunction.stat │ │ ├── Derives.stat │ │ ├── Dialect.stat │ │ ├── Enum.stat │ │ ├── Export.stat │ │ ├── ExportGivens.stat │ │ ├── ExtendsComma.stat │ │ ├── Extension.stat │ │ ├── FewerBraces.stat │ │ ├── FewerBraces_fold.stat │ │ ├── FewerBraces_keep.stat │ │ ├── FewerBraces_unfold.stat │ │ ├── Given.stat │ │ ├── GivenPatterns.stat │ │ ├── ImportingGivens.stat │ │ ├── Infix.stat │ │ ├── InlineTransparent.stat │ │ ├── Issues.stat │ │ ├── Macro.stat │ │ ├── Match.stat │ │ ├── MatchType.stat │ │ ├── OpaqueType.stat │ │ ├── Open.stat │ │ ├── OptionalBraces.stat │ │ ├── OptionalBraces_fold.stat │ │ ├── OptionalBraces_keep.stat │ │ ├── OptionalBraces_unfold.stat │ │ ├── PolyFunction.stat │ │ ├── RenameImportExport.stat │ │ ├── StarImport.stat │ │ ├── TraitParams.stat │ │ ├── Type.stat │ │ ├── TypeLambda.stat │ │ ├── UnionIntersectionType.stat │ │ ├── Using.stat │ │ └── Vararg.stat │ ├── scalajs │ │ ├── Advanced.stat │ │ ├── Apply.stat │ │ ├── Class.stat │ │ ├── DefDef.stat │ │ ├── For.stat │ │ ├── If.stat │ │ ├── Import.source │ │ ├── TermApply.stat │ │ └── Type.stat │ ├── spaces │ │ ├── AfterKeywordBeforeParen.stat │ │ ├── AfterSymbolicDefs.stat │ │ ├── BeforeContextBoundColonIfMultipleBounds.stat │ │ ├── BeforeContextBoundColonTrue.stat │ │ ├── Constructor.stat │ │ ├── Hacking.stat │ │ ├── ImportCurlyBraces.source │ │ ├── InByNameTypes.stat │ │ ├── InParentheses.stat │ │ ├── InterpolatedStringCurlyBraces.stat │ │ ├── NeverAroundInfixTypes.stat │ │ ├── Scalatest.stat │ │ └── TrailingWhiteSpace.stat │ ├── test │ │ ├── BlocksInSingleArg.stat │ │ ├── Class.stat │ │ ├── ContinuationIndent.stat │ │ ├── ContinuationIndentCaseSite0.stat │ │ ├── ContinuationIndentCaseSite1.stat │ │ ├── ContinuationIndentCaseSite5.stat │ │ ├── ContinuationIndentHalfDanglingParens.stat │ │ ├── ContinuationIndentNoDanglingParens.stat │ │ ├── Dangling.stat │ │ ├── Dialect.source │ │ ├── DynamicStyle.stat │ │ ├── ImportSingleLine.source │ │ ├── IndentOperator.stat │ │ ├── IndentOperatorFormatInfix.stat │ │ ├── IndentYieldKeyword.stat │ │ ├── Issue1509.stat │ │ ├── JavaDoc.stat │ │ ├── NoAlign.stat │ │ ├── OperatorSpray.stat │ │ ├── StripMargin.stat │ │ ├── Type747.stat │ │ ├── Unicode.stat │ │ ├── UnindentTopLevelOperatorsOperatorSpray.stat │ │ ├── arityThreshold.source │ │ ├── i1116.stat │ │ ├── i1245.stat │ │ ├── i1300.stat │ │ ├── i1439.stat │ │ ├── i1527.stat │ │ ├── includeNoParensInSelectChains.stat │ │ └── poorMansTrailingCommasInConfigStyle.stat │ ├── trailing-commas │ │ ├── trailingCommasAlways.stat │ │ ├── trailingCommasAlwaysAlignMore.stat │ │ ├── trailingCommasAlwaysComments.stat │ │ ├── trailingCommasAlwaysDanglingParens.stat │ │ ├── trailingCommasAlwaysOwners.stat │ │ ├── trailingCommasAlwaysSingleLine.stat │ │ ├── trailingCommasAlwaysVerticalMultilineAtDefnSite.stat │ │ ├── trailingCommasMultiple.stat │ │ ├── trailingCommasMultipleAlignMore.stat │ │ ├── trailingCommasMultipleComments.stat │ │ ├── trailingCommasMultipleDanglingParens.stat │ │ ├── trailingCommasNever.stat │ │ ├── trailingCommasNeverComments.stat │ │ ├── trailingCommasNeverCommentsAlignMore.stat │ │ ├── trailingCommasNeverSingleLine.stat │ │ └── trailingCommasPreserve.stat │ ├── unit │ │ ├── Advanced.source │ │ ├── Annotations.stat │ │ ├── Apply.stat │ │ ├── ApplyInfix.stat │ │ ├── Argument.source │ │ ├── Basic.source │ │ ├── Case.case │ │ ├── Case.stat │ │ ├── ColumnWidth.source │ │ ├── Comment.stat │ │ ├── Cond.stat │ │ ├── DefDef.stat │ │ ├── Dialect.stat │ │ ├── For.stat │ │ ├── FormatOff.stat │ │ ├── If.stat │ │ ├── Import.source │ │ ├── Interpolate.stat │ │ ├── Lambda.stat │ │ ├── Lit.stat │ │ ├── Markdown.source │ │ ├── Mod.stat │ │ ├── Package.source │ │ ├── Symbol.stat │ │ ├── Template.source │ │ ├── TermApply.stat │ │ ├── TermUpdate.stat │ │ ├── Trait.source │ │ ├── Type.stat │ │ ├── TypeArgument.stat │ │ ├── UnaryApply.stat │ │ ├── Val.stat │ │ └── Xml.stat │ └── vertical-multiline │ │ ├── VerticalMultilineDefnSite.stat │ │ ├── afterImplicitKW.stat │ │ ├── beforeImplicitKW.stat │ │ ├── excludeDanglingInDef.stat │ │ ├── newlineAfterOpenParen.stat │ │ ├── verticalAlignMultilineOperators.stat │ │ ├── verticalMultiline.stat │ │ ├── verticalMultilineDangling.source │ │ ├── verticalMultilineDefnSiteNoDangling.stat │ │ └── withSpacesInParentheses.stat │ └── scala │ └── org │ └── scalafmt │ ├── CommentTest.scala │ ├── CustomStructureTest.scala │ ├── Debug.scala │ ├── EmptyFileTest.scala │ ├── FidelityTest.scala │ ├── FormatTests.scala │ ├── LineEndingsTest.scala │ ├── ManualTests.scala │ ├── RangeTest.scala │ ├── ScalafmtTest.scala │ ├── UnitTests.scala │ ├── config │ ├── AvoidInfixSettingsTest.scala │ ├── ConfigDialectOverrideTest.scala │ ├── RunnerSettingsTest.scala │ ├── ScalafmtConfigTest.scala │ └── StandardProjectLayoutTest.scala │ ├── package.scala │ ├── stats │ ├── GitInfo.scala │ ├── JavaInfo.scala │ ├── MachineStats.scala │ ├── OsInfo.scala │ ├── RuntimeInfo.scala │ └── TestStats.scala │ └── util │ ├── CanRunTests.scala │ ├── DiffTest.scala │ ├── ErrorTest.scala │ ├── FormatAssertions.scala │ ├── FormatOutput.scala │ ├── HasTests.scala │ ├── Report.scala │ ├── Result.scala │ └── StyleMapTest.scala ├── scalafmt.ps1 ├── website ├── .gitignore ├── core │ └── Footer.js ├── i18n │ └── en.json ├── package.json ├── pages │ └── en │ │ ├── index.js │ │ └── users.js ├── sidebars.json ├── siteConfig.js └── static │ ├── css │ ├── code-blocks-buttons.css │ └── custom.css │ ├── img │ ├── favicon.ico │ └── scalameta-logo.png │ └── js │ ├── code-blocks-buttons.js │ └── code-blocks-compare.js └── yarn.lock /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # added oneStatApply to .scalafmt.conf 2 | a1461258dcdf5b6096603ff7de696cf490f3bfa3 3 | # scalafmt v3.8.4-rc4 4 | 1d22de83c0e108fbc1d31b3afc9b62102b3d15fd 5 | # scalafmt redundantXxx = all 6 | b363e86a02b9b754f6d83d82b53b051d97261a88 7 | # scalafmt v3.8.4-rc3 8 | 5e76cc2f3a8766393db0e55a4339462e9ee7ab13 9 | # scalafmt lots of changes 10 | e0a27b5927a3d0dd8d836b666dbc7c713dc26eb1 11 | 6207f8806b15e19174a82db98b2682639f11e45d 12 | ccbe067da4234c8fb20458b772cec5f4cb592374 13 | 62270fe3fea553d20b6c77263a29e376b0384d3f 14 | d76cb7c0df1160049aa59fbbfaab7f9543db5da6 15 | 8c3ec5e53b0a1994fd641614abed3a464a3238b8 16 | d0be16274e954a83074244df3e7f2fe35be92ac1 17 | 4a47f0425dac0bbfd5daaa744891e8b3639772db 18 | 3b7b5616443ede7e3fe3bd9fa316a06e266c2a9b 19 | da8534d89378be7d9b1db4032195abfea73e9619 20 | b713da2d0fcee76fd27f6d2e6dbfacb15e2a1150 21 | # v3.8.6 22 | 6489c56053a833ef10f4c9ab86e0974acceebc79 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * eol=lf 2 | *.png eol=autocrlf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: [] 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | template: | 2 | ## Pull Requests 3 | 4 | $CHANGES 5 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | update_release_draft: 13 | permissions: 14 | contents: write # for release-drafter/release-drafter to create a github release 15 | pull-requests: write # for release-drafter/release-drafter to add label to PR 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: release-drafter/release-drafter@v6 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: [main] 5 | tags: ["*"] 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-java@v4 14 | with: 15 | java-version: '11' 16 | distribution: 'temurin' 17 | cache: 'sbt' 18 | - uses: sbt/setup-sbt@v1 19 | - name: Publish ${{ github.ref }} 20 | run: sbt ci-release docs/docusaurusPublishGhpages 21 | env: 22 | PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} 23 | PGP_SECRET: ${{ secrets.PGP_SECRET }} 24 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 25 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 26 | GIT_USER: scalameta@scalameta.org 27 | GIT_DEPLOY_KEY: ${{ secrets.GIT_DEPLOY_KEY }} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | gh-pages/ 5 | .secrets 6 | 7 | idea/ 8 | 9 | repos.tar.gz 10 | 11 | # sbt specific 12 | .cache 13 | .history 14 | .lib/ 15 | dist/* 16 | target/ 17 | lib_managed/ 18 | src_managed/ 19 | project/boot/ 20 | project/plugins/project/ 21 | 22 | # Scala-IDE specific 23 | .scala_dependencies 24 | .worksheet 25 | .idea 26 | .idea.bak/ 27 | intellij/out 28 | 29 | # Vim 30 | *.orig 31 | *.sw? 32 | 33 | *~ 34 | docs/xx.md 35 | 36 | # metals 37 | .metals/ 38 | metals.sbt 39 | .bloop/ 40 | .vscode 41 | 42 | node_modules/ 43 | .java-version 44 | -------------------------------------------------------------------------------- /.jvmopts: -------------------------------------------------------------------------------- 1 | -Dfile.encoding=UTF8 2 | -Xms1G 3 | -Xmx3G 4 | -XX:ReservedCodeCacheSize=250M 5 | -XX:+TieredCompilation 6 | -XX:-UseGCOverheadLimit 7 | -Dsbt.server.autostart=false 8 | -------------------------------------------------------------------------------- /.scala-steward.conf: -------------------------------------------------------------------------------- 1 | pullRequests.frequency = "@monthly" 2 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version=3.9.6 2 | runner.dialect = scala213 3 | project { 4 | git = true 5 | excludeFilters = [ 6 | scalafmt-benchmarks/src/resources, 7 | sbt-test 8 | bin/issue 9 | ] 10 | layout = StandardConvention 11 | } 12 | align { 13 | preset = none 14 | stripMargin = true 15 | } 16 | newlines { 17 | avoidForSimpleOverflow = all 18 | ignoreInSyntax = false 19 | source = fold 20 | } 21 | rewrite { 22 | rules = [ 23 | AvoidInfix, 24 | Imports, 25 | RedundantBraces, 26 | RedundantParens, 27 | SortModifiers, 28 | ] 29 | imports { 30 | expand = true 31 | sort = ascii 32 | groups = [ 33 | ["org\\.scalafmt\\..*"], 34 | ["scala\\.meta\\..*", "org\\.scalameta\\..*"], 35 | ["sbt\\..*"], 36 | ["java.?\\..*"], 37 | ["scala\\..*"], 38 | ["org\\..*"], 39 | ["com\\..*"], 40 | ] 41 | } 42 | redundantBraces { 43 | preset = all 44 | oneStatApply { 45 | parensMaxSpan = 300 46 | bracesMinSpan = 300 47 | } 48 | } 49 | redundantParens { 50 | preset = all 51 | } 52 | sortModifiers.preset = styleGuide 53 | trailingCommas.style = "always" 54 | } 55 | # Disabled in default since this operation is potentially 56 | # dangerous if you define your own stripMargin with different 57 | # semantics from the stdlib stripMargin. 58 | assumeStandardLibraryStripMargin = true 59 | onTestFailure = "To fix this, run ./scalafmt from the project root directory" 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please refer to the documentation for contributors 4 | [on the website](https://scalameta.org/scalafmt/docs/contributing-scalafmt.html). 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | COPY tmp/scalafmt-docker-build/scalafmt /bin/scalafmt 4 | RUN chmod +x /bin/scalafmt 5 | 6 | ENTRYPOINT ["/bin/scalafmt"] 7 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: 2 | - Visual Studio 2017 3 | build: off 4 | 5 | init: 6 | - git config --global core.autocrlf input 7 | 8 | install: 9 | - ps: iex (new-object net.webclient).downloadstring('https://get.scoop.sh') 10 | - ps: scoop bucket add versions 11 | - ps: scoop install sbt 12 | - SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g -Dsbt.supershell=never -Dfile.encoding=UTF8 13 | 14 | environment: 15 | CI_SCALA_VERSION: 2.12.8 16 | 17 | build_script: 18 | - sbt downloadIdea tests/compile 19 | 20 | test_script: 21 | - sbt coreJVM/test 22 | - sbt ci-test 23 | 24 | cache: 25 | - '%USERPROFILE%\.m2' 26 | - '%USERPROFILE%\.ivy2\cache' 27 | - '%USERPROFILE%\.sbt' 28 | - '%USERPROFILE%\.coursier' 29 | - '%USERPROFILE%\scoop\cache' 30 | -------------------------------------------------------------------------------- /bin/_scalafmt: -------------------------------------------------------------------------------- 1 | #compdef scalafmt 2 | 3 | _scalafmt() { 4 | local -a cmds 5 | 6 | _arguments -C \ 7 | {-h,--help}'[prints usage text]' \ 8 | {-v,--version}'[print version]' \ 9 | '--stdout[write formatted files to stdout]' \ 10 | '--git[if true, ignore files in .gitignore (default false)]:value:' \ 11 | '--exclude[file or directory, in which case all *.scala files are formatted]:value:_files' \ 12 | {-c,--config}'[a file path to .scalafmt.conf]:value:_files' \ 13 | '--config-str[configuration defined as a string]:value:' \ 14 | '--stdin[read from stdin and print to stdout]' \ 15 | '--no-stderr[do not use strerr for messages, output to stdout]' \ 16 | '--assume-filename[when using --stdin, use --assume-filename to hint to scalafmt that the input is an .sbt file]:value:' \ 17 | '--test[test for mis-formatted code, exits with status 1 on failure]' \ 18 | '--migrate2hocon[migrate .scalafmt CLI style configuration to hocon style configuration in .scalafmt.conf]:value:' \ 19 | '--mode diff[if set, only format edited files in git diff against master]' \ 20 | '--diff-branch[if set, only format edited files in git diff against provided branch]:value:' \ 21 | '--build-info[prints build information]' \ 22 | '--quiet[do not print out stuff to console]' \ 23 | '--debug[print out diagnostics to console]' \ 24 | '--non-interactive[disable fancy progress bar, useful in ci or sbt plugin]' 25 | } 26 | 27 | _scalafmt 28 | -------------------------------------------------------------------------------- /bin/build-native-image.sh: -------------------------------------------------------------------------------- 1 | set -eux 2 | sbt "cli/nativeImageCopy scalafmt" -------------------------------------------------------------------------------- /bin/configure: -------------------------------------------------------------------------------- 1 | # For some odd reason the `scalafmt` is not executable when installed 2 | # with brew. This line does the trick. 3 | chmod u+x bin/scalafmt 4 | -------------------------------------------------------------------------------- /bin/repo-commits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Saves the commit has for each clones repo in target/repos 3 | set -e 4 | 5 | for repo in target/repos/*; do 6 | echo $repo ... 7 | git --git-dir="$repo/.git" curr > $repo/COMMIT 8 | git --git-dir="$repo/.git" config --get remote.origin.url > $repo/URL 9 | done 10 | -------------------------------------------------------------------------------- /bin/run-benchmarks.sh: -------------------------------------------------------------------------------- 1 | if [[ ! -f benchmarks/repos.tar.gz ]]; then 2 | if [[ ! -f repos.tar.gz ]]; then 3 | echo "Missing repos.tar.gz, run first sbt test" 4 | exit 1 5 | fi 6 | echo "Extracting repos.tar.gz..." 7 | cp repos.tar.gz benchmarks 8 | cd benchmarks 9 | tar xvf repos.tar.gz &> /dev/null 10 | cd .. 11 | echo "Done!" 12 | fi 13 | prefix=${1-Micro} 14 | iterations=${2-3} 15 | sbt "benchmarks/jmh:run -rf csv -rff target/jmh-results.csv -i $iterations -wi $iterations -f1 -t1 org.scalafmt.benchmarks.$prefix*" 16 | # sbt "core/test:runMain org.scalafmt.FormatExperiment" 17 | 18 | -------------------------------------------------------------------------------- /bin/scalafmt_ng: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | check_binary(){ 4 | command -v "$0" >/dev/null 2>&1 || { echo >&2 "Missing dependency $0, exiting."; exit 1; } 5 | } 6 | 7 | startNailgun() { 8 | echo "Starting nailgun..." >& 2 9 | $JAVA -cp "$default_dir/$scalafmt_filename" com.martiansoftware.nailgun.NGServer & 10 | sleep 1 11 | $NAILGUN ng-alias scalafmt org.scalafmt.cli.Cli 12 | } 13 | 14 | if [[ "$NAILGUN" != "" && -e "$SCALAFMT_HOME/nailgun" ]]; then 15 | $NAILGUN ng-stats &> /dev/null || startNailgun 16 | $NAILGUN scalafmt "$@" 17 | else 18 | $JAVA -jar "$default_dir/$scalafmt_filename" "$@" 19 | fi 20 | -------------------------------------------------------------------------------- /bin/test-release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | 4 | version=$1 5 | 6 | coursier resolve \ 7 | org.scalameta:scalafmt-cli_2.13:$version \ 8 | org.scalameta:scalafmt-cli_2.12:$version 9 | -------------------------------------------------------------------------------- /docs/assets/img/intellij-choose-formatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/docs/assets/img/intellij-choose-formatter.png -------------------------------------------------------------------------------- /docs/assets/img/intellij-install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/docs/assets/img/intellij-install.png -------------------------------------------------------------------------------- /docs/assets/img/intellij-on-save-native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/docs/assets/img/intellij-on-save-native.png -------------------------------------------------------------------------------- /docs/assets/img/intellij-on-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/docs/assets/img/intellij-on-save.png -------------------------------------------------------------------------------- /docs/assets/img/intellij-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/docs/assets/img/intellij-plugin.png -------------------------------------------------------------------------------- /docs/gotchas.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: gotchas 3 | title: Gotchas 4 | --- 5 | 6 | Scalafmt tries to automatically reformat as much as possible. However, sometimes 7 | you need to help scalafmt decide how to format your code. 8 | 9 | ## Infix applications 10 | 11 | Infix applications are methods calls that use the syntax like `a + b` instead of 12 | `a.+(b)`. 13 | 14 | Scalafmt preserves your line breaks in infix applications, even if this means 15 | the `maxColumn` setting is not respected. 16 | 17 | ```scala 18 | // column limit | 19 | // if you have long infix applications 20 | a.b(c) && d.e(f, g, h) 21 | 22 | // then scalafmt may format like this 23 | a.b(c) && d.e( 24 | f, g, h) 25 | 26 | // which is ugly. You can fix it by inserting 27 | // a newline after && and it will look like this 28 | a.b(c) && 29 | d.e(f, g, h) 30 | ``` 31 | 32 | ## Config style 33 | 34 | You can use "config style" to tell scalafmt to break a function application. 35 | 36 | ```scala 37 | // Put newline after opening ( 38 | // and newline before closing ) 39 | // to force one argument on each line. 40 | 41 | // OK: Config style 42 | function( 43 | longerArg1 = defaultValue1, 44 | longerArg2 = defaultValue2, 45 | longerArg3 = defaultValue3 46 | ) 47 | // NOT Config style 48 | function(longerArg1 = defaultValue1, 49 | longerArg2 = defaultValue2, 50 | longerArg3 = defaultValue3) 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: introduction 3 | title: Introduction 4 | --- 5 | 6 | Visit [installation docs](installation.md) 7 | -------------------------------------------------------------------------------- /download_scalafmt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # https://scalameta.org/scalafmt/docs/installation.html#coursier 4 | 5 | version=$1 6 | exec \ 7 | coursier bootstrap \ 8 | org.scalameta:scalafmt-cli_2.13:$version \ 9 | -r sonatype:snapshots \ 10 | --main org.scalafmt.cli.Cli \ 11 | -o scalafmt-$version 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Scalafmt", 3 | "scripts": { 4 | "format": "prettier --write docs", 5 | "format-check": "prettier --check docs" 6 | }, 7 | "devDependencies": { 8 | "prettier": "2.0.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /project/Dependencies.scala: -------------------------------------------------------------------------------- 1 | import sbt.Keys._ 2 | import sbt._ 3 | 4 | import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ 5 | 6 | // scalafmt: { maxColumn = 120, align.preset = more, align.allowOverflow = true } 7 | 8 | object Dependencies { 9 | val metaconfigV = "0.15.0" 10 | val scalametaV = "4.13.6" 11 | val scalacheckV = "1.18.1" 12 | val coursier = "2.1.24" 13 | val munitV = "1.1.0" 14 | val mdocV = mdoc.BuildInfo.version 15 | 16 | private def smorg(pkg: => String, v: String) = Def.setting("org.scalameta" %%% pkg % v) 17 | 18 | val munit = smorg("munit", munitV) 19 | val scalameta = Def.setting( 20 | smorg("scalameta", scalametaV).value 21 | .excludeAll("com.thesamet.scalapb" % s"scalapb-runtime_${scalaBinaryVersion.value}"), 22 | ) 23 | val scalametaIO = smorg("io", scalametaV) 24 | val scalametaTestkit = smorg("testkit", scalametaV) 25 | 26 | private def metaconfig(pkg: String) = smorg(s"metaconfig-$pkg", metaconfigV) 27 | val metaconfigCore = metaconfig("core") 28 | val metaconfigTypesafe = metaconfig("typesafe-config") 29 | val metaconfigSconfig = metaconfig("sconfig") 30 | 31 | } 32 | -------------------------------------------------------------------------------- /project/Mima.scala: -------------------------------------------------------------------------------- 1 | import com.typesafe.tools.mima.core._ 2 | 3 | object Mima { 4 | val ignoredABIProblems: Seq[ProblemFilter] = 5 | // After v0.5, start running mima checks in CI and document breaking changes here. 6 | // See https://github.com/typesafehub/migration-manager/wiki/sbt-plugin#basic-usage 7 | Seq( 8 | // Essentially, only org.scalafmt.Scalafmt is protected by bincompat guarantees. 9 | ProblemFilters.exclude[Problem]("org.scalafmt.cli.*"), 10 | ProblemFilters.exclude[Problem]("org.scalafmt.config.*"), 11 | ProblemFilters.exclude[Problem]("org.scalafmt.internal.*"), 12 | ProblemFilters.exclude[Problem]("org.scalafmt.rewrite.*"), 13 | ProblemFilters.exclude[Problem]("org.scalafmt.util.*"), 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.11.0 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | // scalafmt: { maxColumn = 100, align.preset = more, align.allowOverflow = true } 2 | 3 | resolvers ++= Seq(Classpaths.sbtPluginReleases, Resolver.bintrayIvyRepo("jetbrains", "sbt-plugins")) 4 | 5 | val crossProjectV = "1.3.2" 6 | 7 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1") 8 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.13.1") 9 | 10 | addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.0") 11 | addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.11.1") 12 | 13 | addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4") 14 | 15 | addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % crossProjectV) 16 | addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % crossProjectV) 17 | 18 | addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.6.4") 19 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.4") 20 | addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.4") 21 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0") 22 | addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.6") 23 | 24 | addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.7") 25 | -------------------------------------------------------------------------------- /readme/Intro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/readme/Intro -------------------------------------------------------------------------------- /readme/Matrix.example: -------------------------------------------------------------------------------- 1 | object PrettyMatrix { 2 | // format: off 3 | val identity = Array(1, 0, 0, 4 | 0, 1, 0, 5 | 0, 0, 1) 6 | // format: on 7 | } 8 | -------------------------------------------------------------------------------- /readme/resources/custom.js: -------------------------------------------------------------------------------- 1 | Array 2 | .from(document.getElementsByClassName('scalafmt-configuration-toggle')) 3 | .forEach(function(elem) { 4 | elem.onclick = function() { 5 | elem.parentElement.classList.toggle('collapsed'); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /readme/resources/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/readme/resources/favicon.png -------------------------------------------------------------------------------- /readme/resources/google61cac7acd6a4fdc9.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google61cac7acd6a4fdc9.html 2 | -------------------------------------------------------------------------------- /readme/resources/img/downloads-201703.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/readme/resources/img/downloads-201703.png -------------------------------------------------------------------------------- /readme/resources/img/downloads-intellij-201703.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/readme/resources/img/downloads-intellij-201703.png -------------------------------------------------------------------------------- /readme/stripMargin.example: -------------------------------------------------------------------------------- 1 | // 40 columns | 2 | object StripMargin { 3 | val example1 = 4 | s"""Examples: 5 | | * one 6 | | * two 7 | | * $three 8 | |""".stripMargin 9 | 10 | // pipe character after opening """ 11 | val example2 = 12 | s"""|Examples: 13 | | * one 14 | | * two 15 | | * $three 16 | |""".stripMargin 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/scalafmt -------------------------------------------------------------------------------- /scalafmt-benchmarks/src/main/scala/org/scalafmt/benchmarks/FormatBenchmark.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.benchmarks 2 | 3 | import org.scalafmt.Scalafmt 4 | import org.scalafmt.config.RewriteSettings 5 | import org.scalafmt.config.ScalafmtConfig 6 | import org.scalafmt.rewrite.RedundantBraces 7 | import org.scalafmt.rewrite.SortImports 8 | 9 | trait FormatBenchmark { 10 | def formatRewrite(code: String): String = Scalafmt.formatCode( 11 | code, 12 | baseStyle = ScalafmtConfig.default 13 | .copy(rewrite = RewriteSettings(rules = Seq(SortImports, RedundantBraces))), 14 | ).get 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-benchmarks/src/resources/scala-js/readme.md: -------------------------------------------------------------------------------- 1 | These files are taken from [Scala.js](https://github.com/scala-js/scala-js/). 2 | See attached licence. 3 | -------------------------------------------------------------------------------- /scalafmt-benchmarks/src/resources/scalafmt/Basic.scala: -------------------------------------------------------------------------------- 1 | @ foobar("annot", { 2 | val x = 2 3 | val y = 2 // y=2 4 | x + y 5 | }) 6 | object 7 | a extends b with c { 8 | def 9 | foo[T:Int#Double#Triple, 10 | R <% String]( 11 | @annot1 12 | x 13 | : Int @annot2 = 2 14 | , y: Int = 3): Int = { 15 | "match" match { 16 | case 1 | 2 => 17 | 3 18 | case 2 => 2 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-benchmarks/src/test/scala-2.12/org/scalafmt/benchmarks/BenchmarkOK.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.benchmarks 2 | 3 | import org.scalafmt.benchmarks.Micro.ScalaJsFile 4 | 5 | import benchmarks.MacroBenchmark 6 | import munit.FunSuite 7 | 8 | class TestMacroP extends MacroBenchmark(true, 10) 9 | class TestMacroS extends MacroBenchmark(true, 5) 10 | class TestMicroSmall extends ScalaJsFile("EventSerializers.scala") 11 | class TestMicroMedium extends ScalaJsFile("PrintStreamTest.scala") 12 | 13 | class BenchmarkOK extends FunSuite { 14 | 15 | Seq(new TestMacroP, new TestMacroS).foreach { benchmark => 16 | val name = s"macroBenchmark: $benchmark" 17 | test(name) { 18 | benchmark.testMe() 19 | println(name) 20 | } 21 | } 22 | 23 | Seq(new TestMicroMedium, new TestMicroSmall).foreach { formatBenchmark => 24 | val name = s"microBenchmark: ${formatBenchmark.getClass}" 25 | test(name) { 26 | formatBenchmark.testMe() 27 | println(name) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scalafmt-cli/js/src/main/scala/org/scalafmt/cli/CliOptionsUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import java.io.PrintWriter 4 | import java.io.Writer 5 | 6 | private[scalafmt] trait CliOptionsUtils { 7 | def getConsoleWriter(): Option[PrintWriter] = TermUtils.getJSConsole 8 | .map(console => 9 | new PrintWriter(new Writer { 10 | override def write(cbuf: Array[Char], off: Int, len: Int): Unit = 11 | console.log(new String(cbuf, off, len)) 12 | override def flush(): Unit = {} 13 | override def close(): Unit = {} 14 | }), 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /scalafmt-cli/js/src/main/scala/org/scalafmt/cli/CliUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation._ 5 | 6 | private[scalafmt] trait CliUtils { 7 | protected def getDynamicRunner: Option[ScalafmtRunner] = None 8 | 9 | def readInputLines: Iterator[String] = throw new RuntimeException( 10 | "reading input is not supported; read from file instead", 11 | ) 12 | } 13 | 14 | object CliUtils { 15 | 16 | @JSExportTopLevel("main") 17 | def jsMain(): Unit = { 18 | val args = js.Dynamic.global.process.argv.asInstanceOf[js.Array[String]] 19 | // Drop "node" and script path 20 | Cli.main(args.drop(2).toArray) 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /scalafmt-cli/js/src/main/scala/org/scalafmt/cli/PlatformPollingScheduler.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import scala.scalajs.js.timers._ 4 | 5 | class PlatformPollingScheduler extends PollingScheduler { 6 | override def start( 7 | intervalMs: Int, 8 | )(fn: () => Unit): PollingScheduler.Cancelable = { 9 | val handle = setInterval(intervalMs)(fn()) 10 | () => clearInterval(handle) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /scalafmt-cli/js/src/main/scala/org/scalafmt/cli/TermUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.Date 5 | 6 | private[scalafmt] trait TermUtils { 7 | protected def formatTimestamp(ts: Long): String = new Date(ts).toISOString() 8 | def noConsole = TermUtils.getJSConsole.isEmpty 9 | } 10 | 11 | private[scalafmt] object TermUtils { 12 | def getJSConsole = 13 | if (js.typeOf(js.Dynamic.global.console) == "undefined") None 14 | else Option(js.Dynamic.global.console) 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-cli/jvm-native/src/main/scala/org/scalafmt/cli/PlatformPollingScheduler.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import java.util.concurrent._ 4 | 5 | class PlatformPollingScheduler extends PollingScheduler { 6 | private val scheduler: ScheduledExecutorService = Executors 7 | .newScheduledThreadPool(1) 8 | 9 | override def start( 10 | intervalMs: Int, 11 | )(fn: () => Unit): PollingScheduler.Cancelable = { 12 | val task = new Runnable { 13 | def run(): Unit = fn() 14 | } 15 | val future = scheduler 16 | .scheduleAtFixedRate(task, 0, intervalMs.toLong, TimeUnit.MILLISECONDS) 17 | () => future.cancel(false) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-cli/jvm/src/main/scala/org/scalafmt/cli/CliOptionsUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import java.io.PrintWriter 4 | 5 | private[scalafmt] trait CliOptionsUtils { 6 | def getConsoleWriter(): Option[PrintWriter] = Option(System.console()) 7 | .map(_.writer) 8 | } 9 | -------------------------------------------------------------------------------- /scalafmt-cli/jvm/src/main/scala/org/scalafmt/cli/CliUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import org.scalafmt.sysops.AbsoluteFile 4 | import org.scalafmt.sysops.PlatformRunOps 5 | 6 | import scala.io.Source 7 | 8 | import com.facebook.nailgun.NGContext 9 | 10 | private[scalafmt] trait CliUtils { 11 | def nailMain(nGContext: NGContext): Unit = { 12 | val workingDirectory = AbsoluteFile 13 | .fromPathIfAbsolute(nGContext.getWorkingDirectory).getOrElse( 14 | throw new IllegalStateException( 15 | s"Expected absolute path, " + 16 | s"obtained nGContext.getWorkingDirectory = ${nGContext 17 | .getWorkingDirectory}", 18 | ), 19 | ) 20 | import PlatformRunOps.parasiticExecutionContext 21 | Cli.mainWithOptions( 22 | CliOptions.default.copy(common = 23 | CliOptions.default.common.copy( 24 | cwd = Some(workingDirectory), 25 | out = nGContext.out, 26 | in = nGContext.in, 27 | err = nGContext.err, 28 | ), 29 | ), 30 | nGContext.getArgs: _*, 31 | ).map(exit => nGContext.exit(exit.code)) 32 | } 33 | 34 | protected def getDynamicRunner: Option[ScalafmtRunner] = 35 | Some(ScalafmtDynamicRunner) 36 | 37 | def readInputLines: Iterator[String] = Source.stdin.getLines() 38 | } 39 | -------------------------------------------------------------------------------- /scalafmt-cli/jvm/src/main/scala/org/scalafmt/cli/TermUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import java.sql.Timestamp 4 | 5 | private[scalafmt] trait TermUtils { 6 | 7 | // Copy/pasted over from coursier, but unused in scalafmt 8 | private val format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 9 | protected def formatTimestamp(ts: Long): String = format 10 | .format(new Timestamp(ts)) 11 | 12 | def noConsole = System.console() == null 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-cli/jvm/src/test/scala/org/scalafmt/cli/CliOptionsJVMTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import FileTestOps._ 4 | import munit.FunSuite 5 | 6 | class CliOptionsJVMTest extends FunSuite { 7 | 8 | private val baseCliOptionsWithOut = baseCliOptions 9 | .copy(common = baseCliOptions.common.copy(out = System.out)) 10 | 11 | Seq("--stdin", "--stdout").foreach { arg => 12 | test(s"don't write info when using $arg") { 13 | val options = Cli.getConfig(baseCliOptionsWithOut, arg).get 14 | val cons = System.console() 15 | if (cons ne null) options.common.info match { 16 | case x: Output.FromWriter if x.obj eq cons.writer() => 17 | case x => fail(s"info should be writing to console: $x") 18 | } 19 | else options.common.info match { 20 | case x: Output.FromStream if x.obj eq Output.NoopStream.printStream => 21 | case x => fail(s"info should be writing to NoopStream: $x") 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scalafmt-cli/native/src/main/scala/org/scalafmt/cli/CliOptionsUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import java.io.PrintWriter 4 | 5 | private[scalafmt] trait CliOptionsUtils { 6 | def getConsoleWriter(): Option[PrintWriter] = None 7 | } 8 | -------------------------------------------------------------------------------- /scalafmt-cli/native/src/main/scala/org/scalafmt/cli/CliUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import scala.io.Source 4 | 5 | private[scalafmt] trait CliUtils { 6 | protected def getDynamicRunner: Option[ScalafmtRunner] = None 7 | 8 | def readInputLines: Iterator[String] = Source.stdin.getLines() 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-cli/native/src/main/scala/org/scalafmt/cli/TermUtils.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | private[scalafmt] trait TermUtils { 4 | 5 | // Copy/pasted over from coursier, but not used in scalafmt 6 | protected def formatTimestamp(ts: Long): String = ??? 7 | 8 | def noConsole = false 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-cli/shared/src/main/resources/META-INF/native-image/org.scalafmt/scalafmt-cli/native-image.properties: -------------------------------------------------------------------------------- 1 | Args=--no-server \ 2 | -Dscalafmt.native-image=true \ 3 | --no-fallback \ 4 | --enable-http \ 5 | --enable-https \ 6 | --install-exit-handlers \ 7 | --strict-image-heap \ 8 | -march=native \ 9 | --initialize-at-build-time="org.scalafmt" \ 10 | --initialize-at-build-time="org.scalameta" \ 11 | --initialize-at-build-time="scala.meta" \ 12 | --report-unsupported-elements-at-runtime \ 13 | -H:+UnlockExperimentalVMOptions \ 14 | -H:+RemoveSaturatedTypeFlows \ 15 | -H:+ReportExceptionStackTraces \ 16 | -H:-UnlockExperimentalVMOptions 17 | -------------------------------------------------------------------------------- /scalafmt-cli/shared/src/main/resources/META-INF/native-image/org.scalafmt/scalafmt-cli/reflection.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", 4 | "allDeclaredConstructors": true, 5 | "allPublicConstructors": true, 6 | "allDeclaredMethods": true, 7 | "allPublicMethods": true, 8 | "allDeclaredClasses": true, 9 | "allPublicClasses": true 10 | } 11 | ] -------------------------------------------------------------------------------- /scalafmt-cli/shared/src/main/scala/org/scalafmt/cli/PollingScheduler.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | object PollingScheduler { 4 | trait Cancelable { 5 | def cancel(): Unit 6 | } 7 | } 8 | 9 | trait PollingScheduler { 10 | 11 | /** Start polling at the given interval. The function is executed * 12 | * periodically. 13 | */ 14 | def start(intervalMs: Int)(fn: () => Unit): PollingScheduler.Cancelable 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-cli/shared/src/main/scala/org/scalafmt/cli/WriteMode.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | /** Determines the mode in which Scalafmt will behave 4 | * 5 | * - Override: Replace the file with its formatted form 6 | * - Stdout: Print the formatted file to Stdout (leaving the original file 7 | * untouched) 8 | */ 9 | sealed trait WriteMode { 10 | val usesOut: Boolean 11 | } 12 | 13 | object WriteMode { 14 | 15 | case object Override extends WriteMode { 16 | val usesOut: Boolean = false 17 | } 18 | 19 | case object Stdout extends WriteMode { 20 | val usesOut: Boolean = true 21 | } 22 | 23 | case object List extends WriteMode { 24 | val usesOut: Boolean = true 25 | } 26 | 27 | case object Test extends WriteMode { 28 | val usesOut: Boolean = false 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scalafmt-cli/shared/src/test/scala/org/scalafmt/cli/FakeGitOps.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.cli 2 | 3 | import org.scalafmt.sysops.AbsoluteFile 4 | import org.scalafmt.sysops.GitOps 5 | 6 | class FakeGitOps(root: AbsoluteFile) extends GitOps { 7 | override def lsTree(dir: AbsoluteFile*): Seq[AbsoluteFile] = dir 8 | .flatMap(_.listFiles) 9 | override def rootDir: Option[AbsoluteFile] = Some(root) 10 | override def status(dir: AbsoluteFile*): Seq[AbsoluteFile] = lsTree(root) 11 | override def diff(branch: String, dir: AbsoluteFile*): Seq[AbsoluteFile] = 12 | lsTree(dir: _*) 13 | override def getAutoCRLF: Option[String] = None 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-config/js/src/main/scala/org/scalafmt/config/PlatformConfig.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | object PlatformConfig { 6 | implicit val parser: MetaconfigParser = sconfig.sConfigMetaconfigParser 7 | } 8 | -------------------------------------------------------------------------------- /scalafmt-config/jvm/src/main/scala/org/scalafmt/config/PlatformConfig.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | object PlatformConfig { 6 | implicit val parser: MetaconfigParser = 7 | typesafeconfig.typesafeConfigMetaconfigParser 8 | } 9 | -------------------------------------------------------------------------------- /scalafmt-config/native/src/main/scala/org/scalafmt/config/PlatformConfig.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | object PlatformConfig { 6 | implicit val parser: MetaconfigParser = sconfig.sConfigMetaconfigParser 7 | } 8 | -------------------------------------------------------------------------------- /scalafmt-core/js/src/main/scala/org/scalafmt/config/Platform.config: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/scalafmt-core/js/src/main/scala/org/scalafmt/config/Platform.config -------------------------------------------------------------------------------- /scalafmt-core/jvm/src/main/scala/org/scalafmt/internal/PriorityQueue.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | /** Minimal implementation of the PriorityQueue's functions needed. 4 | * 5 | * We use `java.util.PriorityQueue` to enable usage under GraalVM. The 6 | * native-image compiler is unable to work with 7 | * `scala.collection.mutable.PriorityQueue` currently. 8 | * 9 | * @tparam T 10 | * the values inside the queue 11 | */ 12 | class PriorityQueue[T](implicit ord: Ordering[T]) { 13 | private[this] val q = new java.util.PriorityQueue[T](11, ord.reversed()) 14 | 15 | def dequeueAll(): Unit = q.clear() 16 | 17 | def dequeue(): T = q.poll() 18 | 19 | def size: Int = q.size() 20 | 21 | def enqueue(x: T): Unit = q.add(x) 22 | 23 | def +=(x: T): PriorityQueue[T] = { 24 | q.add(x) 25 | this 26 | } 27 | 28 | def nonEmpty: Boolean = !isEmpty 29 | 30 | def isEmpty: Boolean = q.isEmpty 31 | 32 | } 33 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala-2.12/scala/collection/mutable/package.scala: -------------------------------------------------------------------------------- 1 | package scala.collection 2 | 3 | package object mutable { 4 | 5 | implicit class ImplicitMap[K, V](private val obj: Map[K, V]) extends AnyVal { 6 | def updateWith( 7 | key: K, 8 | )(remappingFunction: Option[V] => Option[V]): Option[V] = obj.get(key) match { 9 | case vOldOpt @ Some(vOld) => 10 | val vOpt = remappingFunction(vOldOpt) 11 | vOpt match { 12 | case Some(v) => if (v != vOld) obj.update(key, v) 13 | case None => obj.remove(key) 14 | } 15 | vOpt 16 | case None => 17 | val vOpt = remappingFunction(None) 18 | vOpt.foreach(v => obj.update(key, v)) 19 | vOpt 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/Formatted.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | 5 | import scala.util.Try 6 | 7 | sealed abstract class Formatted { 8 | 9 | def toEither: Either[Throwable, String] = this match { 10 | case Formatted.Success(s) => Right(s) 11 | case Formatted.Failure(e) => Left(e) 12 | } 13 | 14 | def get: String = this match { 15 | case Formatted.Success(code) => code 16 | case Formatted.Failure(e) => throw e 17 | } 18 | } 19 | 20 | object Formatted { 21 | case class Success(formattedCode: String) extends Formatted 22 | case class Failure(e: Throwable) extends Formatted 23 | 24 | def apply(formatted: Try[String]): Formatted = formatted 25 | .fold(Failure.apply, Success.apply) 26 | 27 | private[scalafmt] case class Result( 28 | formatted: Formatted, 29 | config: ScalafmtConfig, 30 | ) { 31 | def get: String = formatted.get 32 | } 33 | 34 | private[scalafmt] object Result { 35 | def apply(res: Try[String], config: ScalafmtConfig): Result = 36 | Result(Formatted(res), config) 37 | def apply(res: Throwable, config: ScalafmtConfig): Result = 38 | Result(Failure(res), config) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/Config.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | // this class is used in older versions of scalafmt-dynamic, keep it here 4 | object Config {} 5 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/FormatEvent.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import org.scalafmt.internal._ 4 | 5 | /** An event that happens while formatting a file. 6 | */ 7 | sealed abstract class FormatEvent 8 | 9 | object FormatEvent { 10 | case class CreateFormatOps(formatOps: FormatOps) extends FormatEvent 11 | case class Routes(routes: IndexedSeq[Seq[Split]]) extends FormatEvent 12 | case class VisitToken(formatToken: FT) extends FormatEvent 13 | case class Explored(n: Int, depth: Int, queueSize: Int) extends FormatEvent 14 | case class Enqueue(split: Split) extends FormatEvent 15 | case class CompleteFormat( 16 | totalExplored: Int, 17 | finalState: State, 18 | visits: IndexedSeq[Int], 19 | best: collection.Map[Int, State], 20 | ) extends FormatEvent 21 | case class Written(formatLocations: FormatWriter#FormatLocations) 22 | extends FormatEvent 23 | } 24 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/LineEndings.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | sealed abstract class LineEndings 6 | 7 | object LineEndings { 8 | implicit val reader: ConfCodecEx[LineEndings] = ReaderUtil 9 | .oneOfCustom[LineEndings](unix, windows, preserve) { 10 | case Conf.Str("keep") => Configured.Ok(preserve) 11 | } 12 | case object unix extends LineEndings 13 | case object windows extends LineEndings 14 | case object preserve extends LineEndings 15 | 16 | def eol(isWin: Boolean): String = if (isWin) "\r\n" else "\n" 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/Literals.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import Literals.Case 4 | import metaconfig._ 5 | 6 | case class Literals( 7 | long: Case = Case.Upper, 8 | float: Case = Case.Lower, 9 | double: Case = Case.Lower, 10 | hexDigits: Case = Case.Lower, 11 | hexPrefix: Case = Case.Lower, 12 | binPrefix: Case = Case.Lower, 13 | scientific: Case = Case.Lower, 14 | ) 15 | 16 | object Literals { 17 | implicit val surface: generic.Surface[Literals] = generic.deriveSurface 18 | implicit val codec: ConfCodecEx[Literals] = generic.deriveCodecEx(Literals()) 19 | .noTypos 20 | 21 | sealed abstract class Case { 22 | import Case._ 23 | def process(str: String): String = this match { 24 | case Unchanged => str 25 | case Lower => str.toLowerCase() 26 | case Upper => str.toUpperCase() 27 | } 28 | } 29 | 30 | object Case { 31 | implicit val codec: ConfCodecEx[Case] = ReaderUtil 32 | .oneOf[Case](Upper, Lower, Unchanged) 33 | case object Upper extends Case 34 | case object Lower extends Case 35 | case object Unchanged extends Case 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/RedundantParensSettings.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | case class RedundantParensSettings( 6 | infixSide: Option[RedundantParensSettings.InfixSide] = None, 7 | ) 8 | 9 | object RedundantParensSettings { 10 | val default = RedundantParensSettings() 11 | private[scalafmt] val all = 12 | RedundantParensSettings(infixSide = Some(InfixSide.all)) 13 | 14 | private implicit val preset 15 | : PartialFunction[Conf, RedundantParensSettings] = { 16 | case Conf.Str("default") => default 17 | case Conf.Str("all") => all 18 | } 19 | 20 | implicit lazy val surface: generic.Surface[RedundantParensSettings] = 21 | generic.deriveSurface 22 | implicit lazy val encoder: ConfEncoder[RedundantParensSettings] = 23 | generic.deriveEncoder 24 | implicit lazy val decoder: ConfDecoderEx[RedundantParensSettings] = Presets 25 | .mapDecoder(generic.deriveDecoderEx(default).noTypos, "RedundantParens") 26 | 27 | sealed abstract class InfixSide 28 | object InfixSide { 29 | implicit val codec: ConfCodecEx[InfixSide] = ReaderUtil 30 | .oneOf[InfixSide](all, many, some) 31 | case object all extends InfixSide 32 | case object many extends InfixSide 33 | case object some extends InfixSide 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/ScalafmtConfDecoders.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import scala.meta.parsers.Parse._ 4 | 5 | import scala.io.Codec 6 | 7 | import metaconfig._ 8 | 9 | object ScalafmtConfDecoders extends ScalafmtConfDecoders 10 | 11 | trait ScalafmtConfDecoders { 12 | implicit def eventReaderFor[A <: FormatEvent]: ConfDecoderEx[A => Unit] = 13 | ConfDecoderEx.from[A => Unit] { case _ => Configured.Ok((_: A) => ()) } 14 | 15 | implicit lazy val parseReader: ConfCodecEx[MetaParser] = ReaderUtil 16 | .oneOf[MetaParser](parseSource, parseStat, parseCase) 17 | 18 | implicit lazy val codecReader: ConfDecoderEx[Codec] = ConfDecoderEx 19 | .fromPartial[Codec]("String") { case (_, Conf.Str(s)) => 20 | Configured.fromExceptionThrowing(Codec(s)) 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/ScalafmtConfigException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | class ScalafmtConfigException(e: String) extends Exception(e) 4 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/ScalafmtParser.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import scala.meta._ 4 | import scala.meta.parsers.Parse 5 | import scala.meta.parsers.Parsed 6 | 7 | import metaconfig.ConfCodecEx 8 | 9 | sealed class ScalafmtParser(val parse: Parse[_ <: Tree]) 10 | 11 | object ScalafmtParser { 12 | case object Case extends ScalafmtParser(Parse.parseCase) 13 | case object Stat extends ScalafmtParser(Parse.parseStat) 14 | case object Source extends ScalafmtParser(SourceParser) 15 | 16 | implicit val codec: ConfCodecEx[ScalafmtParser] = ReaderUtil 17 | .oneOf[ScalafmtParser](Case, Stat, Source) 18 | 19 | private object SourceParser extends Parse[Tree] { 20 | override def apply(input: Input, dialect: Dialect): Parsed[Tree] = { 21 | val isAmmonite = input.isInstanceOf[Input.Ammonite] 22 | val parser = if (isAmmonite) Parse.parseAmmonite else Parse.parseSource 23 | parser(input, dialect) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/VerticalMultiline.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | /** Configuration related to multi-line formatting. 6 | */ 7 | case class VerticalMultiline( 8 | atDefnSite: Boolean = false, 9 | arityThreshold: Int = 100, 10 | newlineAfterOpenParen: Boolean = false, 11 | ) 12 | 13 | object VerticalMultiline { 14 | implicit lazy val surface: generic.Surface[VerticalMultiline] = 15 | generic.deriveSurface 16 | implicit lazy val codec: ConfCodecEx[VerticalMultiline] = generic 17 | .deriveCodecEx(VerticalMultiline()).noTypos 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/XmlLiterals.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import metaconfig._ 4 | 5 | case class XmlLiterals(assumeFormatted: Boolean = false) 6 | 7 | object XmlLiterals { 8 | implicit val surface: generic.Surface[XmlLiterals] = generic.deriveSurface 9 | implicit lazy val codec: ConfCodecEx[XmlLiterals] = generic 10 | .deriveCodecEx(XmlLiterals()).noTypos 11 | } 12 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/config/package.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.meta._ 4 | 5 | import scala.language.implicitConversions 6 | 7 | package object config extends ScalafmtConfDecoders { 8 | type MetaParser = parsers.Parse[_ <: Tree] 9 | 10 | type NamedDialect = sourcecode.Text[Dialect] 11 | 12 | implicit def toDialect(nd: NamedDialect): Dialect = nd.value 13 | 14 | implicit class ImplicitNamedDialect(private val nd: NamedDialect) 15 | extends AnyVal { 16 | def name: String = nd.source 17 | def dialect: Dialect = nd.value 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Constants.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | object Constants { 4 | val ShouldBeNewline = 100000 5 | val ShouldBeSingleLine = 30 6 | val BinPackAssignmentPenalty = 10 7 | val SparkColonNewline = 10 8 | val BracketPenalty = 20 9 | val ExceedColumnPenalty = 1000 10 | // Breaking a line like s"aaaaaaa${111111 + 22222}" should be last resort. 11 | val BreakSingleLineInterpolatedString = 1000 * ExceedColumnPenalty 12 | } 13 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FileLineStack.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | import org.scalameta.FileLine 4 | 5 | class FileLineStack private ( 6 | val fileLineHead: FileLine, 7 | val fileLineLast: FileLine, 8 | ) extends Ordered[FileLineStack] { 9 | override def toString: String = s"$fileLineHead->$fileLineLast" 10 | 11 | def forThisLine(implicit 12 | file: sourcecode.File, 13 | line: sourcecode.Line, 14 | ): FileLineStack = new FileLineStack( 15 | fileLineHead = fileLineHead, 16 | fileLineLast = FileLine.generate, 17 | ) 18 | 19 | override def compare(that: FileLineStack): Int = Integer 20 | .compare(this.fileLineHead.line.value, that.fileLineHead.line.value) 21 | } 22 | 23 | object FileLineStack { 24 | implicit def generate(implicit 25 | file: sourcecode.File, 26 | line: sourcecode.Line, 27 | fileLineHead: FileLine, 28 | ): FileLineStack = new FileLineStack(fileLineHead, FileLine.generate) 29 | 30 | def nextLine(implicit fl: FileLine): FileLine = { 31 | val line = fl.line 32 | new FileLine(fl.file, line.copy(value = line.value + 1)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/PolicySummary.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | import org.scalafmt.util.LoggerOps 4 | 5 | import scala.meta.tokens.{Token => T} 6 | 7 | class PolicySummary(val policies: Seq[Policy]) extends AnyVal { 8 | import LoggerOps._ 9 | 10 | @inline 11 | def noDequeue = policies.exists(_.noDequeue) 12 | 13 | def combine(split: Split, nextft: FT): PolicySummary = 14 | if (nextft.right.is[T.EOF]) PolicySummary.empty 15 | else new PolicySummary( 16 | (split.policy +: policies).flatMap(_.unexpiredOpt(split, nextft)) 17 | .sortBy(_.rank), 18 | ) 19 | 20 | def execute(decision: Decision, debug: Boolean = false): Seq[Split] = policies 21 | .foldLeft(decision) { case (result, policy) => 22 | def withSplits(splits: Seq[Split]): Decision = { 23 | if (debug) logger.debug(s"$policy defined at $result") 24 | result.withSplits(splits) 25 | } 26 | policy.f.andThen(withSplits _).applyOrElse(result, identity[Decision]) 27 | }.splits 28 | 29 | @inline 30 | def exists(f: Policy => Boolean): Boolean = policies.exists(f) 31 | } 32 | 33 | object PolicySummary { 34 | val empty = new PolicySummary(Seq.empty) 35 | } 36 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Side.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | sealed abstract class Side { 4 | def isLeft: Boolean = this == Side.Left 5 | } 6 | 7 | object Side { 8 | case object Right extends Side 9 | case object Left extends Side 10 | } 11 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/SplitTag.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.internal 2 | 3 | sealed abstract class SplitTag { 4 | 5 | final def activateOnly(splits: Seq[Split]): Seq[Split] = splits 6 | .map(_.activateFor(this)) 7 | 8 | } 9 | 10 | object SplitTag { 11 | 12 | case object OneArgPerLine extends SplitTag 13 | case object SelectChainFirstNL extends SplitTag 14 | case object SelectChainSecondNL extends SplitTag 15 | case object SelectChainBinPackNL extends SplitTag 16 | case object InfixChainNoNL extends SplitTag 17 | case object OnelineWithChain extends SplitTag 18 | case object VerticalMultilineSingleLine extends SplitTag 19 | 20 | } 21 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/internal/package.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.language.implicitConversions 4 | 5 | package object internal { 6 | 7 | private[scalafmt] type FT = FormatToken 8 | private[scalafmt] val FT = FormatToken 9 | 10 | private[scalafmt] implicit def implicitModToModExt( 11 | mod: Modification, 12 | ): ModExt = ModExt(mod) 13 | 14 | private[scalafmt] implicit class ImplicitModification( 15 | private val mod: Modification, 16 | ) extends AnyVal { 17 | def toExt: ModExt = mod 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/RemoveEmptyDocstrings.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.rewrite 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | import org.scalafmt.internal._ 5 | 6 | import scala.meta._ 7 | import scala.meta.tokens.{Token => T} 8 | 9 | object RemoveEmptyDocstrings 10 | extends FormatTokensRewrite.Rule with FormatTokensRewrite.RuleFactory { 11 | 12 | import FormatTokensRewrite._ 13 | 14 | override def enabled(implicit style: ScalafmtConfig): Boolean = 15 | style.docstrings.removeEmpty 16 | 17 | override def create(implicit ftoks: FormatTokens): FormatTokensRewrite.Rule = 18 | this 19 | 20 | override def onToken(implicit 21 | ft: FT, 22 | session: Session, 23 | style: ScalafmtConfig, 24 | ): Option[Replacement] = { 25 | val skip = ft.right.is[T.Comment] && 26 | FormatWriter.isEmptyDocstring(ft.meta.right.text) 27 | if (skip) Some(removeToken) else None 28 | } 29 | 30 | override def onRight(lt: Replacement, hasFormatOff: Boolean)(implicit 31 | ft: FT, 32 | session: Session, 33 | style: ScalafmtConfig, 34 | ): Option[(Replacement, Replacement)] = None 35 | 36 | } 37 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/util/LogLevel.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | sealed abstract class LogLevel(color: String)(implicit name: sourcecode.Name) { 4 | override def toString: String = s"[$color${name.value}${Console.RESET}]" 5 | } 6 | 7 | object LogLevel { 8 | case object trace extends LogLevel(Console.RESET) 9 | case object debug extends LogLevel(Console.GREEN) 10 | case object info extends LogLevel(Console.BLUE) 11 | case object warn extends LogLevel(Console.YELLOW) 12 | case object error extends LogLevel(Console.RED) 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-core/shared/src/main/scala/org/scalafmt/util/MarkdownParser.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | import scala.util.Success 4 | import scala.util.Try 5 | 6 | import mdoc.parser._ 7 | 8 | private[scalafmt] object MarkdownParser { 9 | 10 | private val settings: ParserSettings = new ParserSettings { 11 | override val allowCodeFenceIndented: Boolean = true 12 | } 13 | 14 | def transformMdoc(code: String)(fmt: String => Try[String]): Try[String] = { 15 | var hadFencedParts = false 16 | val parts = MarkdownPart.parse(code, settings) 17 | parts.foreach { 18 | case p: CodeFence if p.getMdocMode.isDefined => 19 | val old = p.body.value 20 | fmt(old) match { 21 | case Success(b) => 22 | hadFencedParts = true 23 | p.newBody = Some(if (old.endsWith("\n")) b else b.trim) 24 | case failure => return failure // RETURNING! 25 | } 26 | case _ => 27 | } 28 | 29 | Success(if (hadFencedParts) { 30 | val out = new StringBuilder() 31 | parts.foreach(_.renderToString(out)) 32 | if (out.last != '\n') out.append('\n') 33 | out.toString() 34 | } else code) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-docs/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /scalafmt-docs/src/main/scala/docs/DefaultsModifier.scala: -------------------------------------------------------------------------------- 1 | package docs 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | 5 | import scala.meta.inputs.Input 6 | import scala.meta.inputs.Position 7 | 8 | import mdoc._ 9 | import metaconfig._ 10 | 11 | class DefaultsModifier extends StringModifier { 12 | override val name: String = "defaults" 13 | private val default = ConfEncoder[ScalafmtConfig] 14 | .writeObj(ScalafmtConfig.default) 15 | 16 | override def process(info: String, code: Input, reporter: Reporter): String = 17 | if (info == "all") { 18 | val result = Conf.printHocon(ScalafmtConfig.default) 19 | "```\n" + result + "\n```" 20 | } else { 21 | def getDefaultValue(param: String): String = { 22 | val path = param.split("\\.").toList 23 | val down = path.foldLeft(default.dynamic)(_ selectDynamic _) 24 | down.asConf.fold { e => 25 | reporter.error(Position.Range(code, 0, 0), e.toString()) 26 | "" 27 | }(_.toString()) 28 | } 29 | 30 | val params = code.text.split("\\s+") 31 | if (params.length == 1) { 32 | val param = params(0) 33 | s"Default: `$param = ${getDefaultValue(param)}`\n" 34 | } else { 35 | val defaults = params.map(param => s"$param = ${getDefaultValue(param)}") 36 | ScalafmtModifier 37 | .mdConfigCodeBlock(defaults.mkString("# Defaults\n", "\n", "")) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /scalafmt-docs/src/main/scala/docs/Docusaurus.scala: -------------------------------------------------------------------------------- 1 | package docs 2 | 3 | import java.nio.file.Paths 4 | import java.util.concurrent.ExecutorService 5 | import java.util.concurrent.Executors 6 | 7 | final class Docusaurus(getProcess: () => Process, executor: ExecutorService) { 8 | private def process = getProcess() 9 | private def pid(): Int = { 10 | val cls = process.getClass.getName 11 | assert(cls.contains("UNIXProcess"), cls) 12 | val field = process.getClass.getDeclaredField("pid") 13 | field.setAccessible(true) 14 | field.get(process).asInstanceOf[Int] 15 | } 16 | def kill(): Unit = { 17 | Runtime.getRuntime.exec(s"kill -2 ${pid()}").destroy() 18 | executor.shutdown() 19 | process.destroy() 20 | } 21 | 22 | } 23 | 24 | object Docusaurus { 25 | 26 | def start(): Docusaurus = { 27 | val npm = Executors.newFixedThreadPool(1) 28 | var process: Process = null 29 | npm.submit(new Runnable { 30 | override def run(): Unit = { 31 | val cwd = Paths.get("website").toFile 32 | process = new java.lang.ProcessBuilder("npm", "start").inheritIO() 33 | .directory(cwd).start() 34 | } 35 | }) 36 | new Docusaurus(() => process, npm) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /scalafmt-docs/src/main/scala/docs/FileModifier.scala: -------------------------------------------------------------------------------- 1 | package docs 2 | 3 | import scala.meta.inputs.Input 4 | import scala.meta.inputs.Position 5 | import scala.meta.internal.io.FileIO 6 | import scala.meta.internal.io.PathIO 7 | import scala.meta.io.AbsolutePath 8 | 9 | import java.nio.charset.StandardCharsets 10 | 11 | import mdoc.Reporter 12 | import mdoc.StringModifier 13 | import mdoc.internal.pos.PositionSyntax._ 14 | 15 | class FileModifier extends StringModifier { 16 | val name = "file" 17 | override def process( 18 | info: String, 19 | code: Input, 20 | reporter: Reporter, 21 | ): String = { 22 | val file = AbsolutePath(info) 23 | if (file.isFile) { 24 | val text = FileIO.slurp(file, StandardCharsets.UTF_8).trim 25 | val language = PathIO.extension(file.toNIO) match { 26 | case "scala" => "scala" 27 | case "md" => "md" 28 | case _ => "text" 29 | } 30 | s""" 31 | File: [${file.toNIO 32 | .getFileName}](https://github.com/scalameta/mdoc/blob/master/$info) 33 | `````$language 34 | $text 35 | ````` 36 | """ 37 | } else { 38 | val pos = Position.Range(code, 0 - info.length - 1, 0 - 1) 39 | .toUnslicedPosition 40 | reporter.error(pos, s"no such file: $file") 41 | "" 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /scalafmt-docs/src/main/scala/docs/Main.scala: -------------------------------------------------------------------------------- 1 | package docs 2 | 3 | import org.scalafmt.Versions 4 | 5 | import java.nio.file.Paths 6 | 7 | object Main { 8 | 9 | def main(args: Array[String]): Unit = { 10 | // val docusaurus = Docusaurus.start() 11 | val settings = mdoc.MainSettings() 12 | .withOut(Paths.get("website", "target", "docs")).withSiteVariables(Map( 13 | "VERSION" -> Versions.version, 14 | "STABLE_VERSION" -> Versions.stable, 15 | "SCALAMETA_VERSION" -> Versions.scalameta, 16 | )).withStringModifiers(List( 17 | new FileModifier, 18 | new ScalafmtModifier, 19 | new DefaultsModifier, 20 | )).withArgs(args.toList) 21 | val exit = mdoc.Main.process(settings) 22 | 23 | if (exit != 0) sys.exit(exit) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/resources/META-INF/services/org.scalafmt.interfaces.Scalafmt: -------------------------------------------------------------------------------- 1 | org.scalafmt.dynamic.ScalafmtDynamic 2 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/ConsoleScalafmtReporter.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic 2 | 3 | import org.scalafmt.interfaces.ScalafmtReporter 4 | 5 | import java.io.OutputStreamWriter 6 | import java.io.PrintStream 7 | import java.io.PrintWriter 8 | import java.nio.file.Path 9 | 10 | object ConsoleScalafmtReporter extends ConsoleScalafmtReporter(System.err) 11 | 12 | class ConsoleScalafmtReporter(out: PrintStream) extends ScalafmtReporter { 13 | override def error(file: Path, e: Throwable): Unit = { 14 | out.print(s"error: $file: ") 15 | trimStacktrace(e) 16 | e.printStackTrace(out) 17 | } 18 | 19 | override def error(path: Path, message: String): Unit = out 20 | .println(s"error: $path: $message") 21 | 22 | override def excluded(filename: Path): Unit = out 23 | .println(s"file excluded: $filename") 24 | 25 | override def parsedConfig(config: Path, scalafmtVersion: String): Unit = out 26 | .println(s"parsed config (v$scalafmtVersion): $config") 27 | 28 | override def downloadWriter(): PrintWriter = new PrintWriter(out) 29 | 30 | override def downloadOutputStreamWriter(): OutputStreamWriter = 31 | new OutputStreamWriter(out) 32 | 33 | protected def trimStacktrace(e: Throwable): Unit = () 34 | } 35 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/Dependency.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic 2 | 3 | case class Dependency(group: String, artifact: String, version: String) 4 | 5 | object Dependency { 6 | 7 | def dependencies(version: ScalafmtVersion): Seq[Dependency] = { 8 | val scalaVersion = getScalaVersion(version) 9 | val scalaBinaryVersion = getScalaBinaryVersion(scalaVersion) 10 | val core = "scalafmt-core_" + scalaBinaryVersion 11 | Seq( 12 | Dependency(organization(version), core, version.toString), 13 | Dependency("org.scala-lang", "scala-reflect", scalaVersion), 14 | ) 15 | } 16 | 17 | @inline 18 | private def getScalaBinaryVersion(scalaVersion: String): String = scalaVersion 19 | .substring(0, scalaVersion.lastIndexOf('.')) 20 | 21 | @inline 22 | private def getScalaVersion(version: ScalafmtVersion): String = 23 | if (version < ScalafmtVersion(0, 7, 0)) "2.11.12" 24 | else if (version < ScalafmtVersion(2, 1, 2)) BuildInfo.scala212 25 | else BuildInfo.scala 26 | 27 | @inline 28 | private def organization(version: ScalafmtVersion): String = 29 | if (version < ScalafmtVersion(2, 0, 0, 2)) "com.geirsson" 30 | else "org.scalameta" 31 | 32 | } 33 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/DependencyDownloader.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic 2 | 3 | import java.net.URL 4 | 5 | import scala.util.Try 6 | 7 | trait DependencyDownloader { 8 | def download(dependencies: Seq[Dependency]): Try[Seq[URL]] 9 | } 10 | 11 | trait DependencyDownloaderFactory { 12 | def create(properties: ScalafmtProperties): DependencyDownloader 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/ScalafmtProperties.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic 2 | 3 | import org.scalafmt.dynamic.ScalafmtDynamicError._ 4 | import org.scalafmt.interfaces._ 5 | 6 | import java.nio.file.Path 7 | 8 | final case class ScalafmtProperties( 9 | reporter: ScalafmtReporter = ConsoleScalafmtReporter, 10 | repositories: Seq[String] = Nil, 11 | repositoryCredentials: Seq[RepositoryCredential] = Nil, 12 | respectExcludeFilters: Boolean = true, 13 | ) { 14 | 15 | def withReporter(value: ScalafmtReporter): ScalafmtProperties = 16 | copy(reporter = value) 17 | 18 | def withRespectProjectFilters(value: Boolean): ScalafmtProperties = 19 | copy(respectExcludeFilters = value) 20 | 21 | def withMavenRepositories(value: Seq[String]): ScalafmtProperties = 22 | copy(repositories = value) 23 | 24 | def withRepositoryCredentials( 25 | value: Seq[RepositoryCredential], 26 | ): ScalafmtProperties = copy(repositoryCredentials = value) 27 | 28 | def reportError(file: Path, error: ScalafmtDynamicError): Unit = error match { 29 | case _: ConfigMissingVersion => reporter 30 | .missingVersion(file, BuildInfo.stable) 31 | case _ => reporter.error(file, error.getMessage, error.getCause) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/exceptions/PositionExceptionImpl.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic.exceptions 2 | 3 | import org.scalafmt.interfaces.PositionException 4 | 5 | import java.nio.file.Path 6 | 7 | case class PositionExceptionImpl( 8 | file: Path, 9 | code: String, 10 | shortMessage: String, 11 | longMessage: String, 12 | pos: RangePosition, 13 | cause: Throwable, 14 | ) extends PositionException(longMessage, cause) { 15 | def start: Int = pos.start 16 | def end: Int = pos.end 17 | override def startLine: Int = pos.startLine 18 | override def startCharacter: Int = pos.startCharacter 19 | override def endLine: Int = pos.endLine 20 | override def endCharacter: Int = pos.endCharacter 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/exceptions/RangePosition.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic.exceptions 2 | 3 | case class RangePosition( 4 | start: Int, 5 | startLine: Int, 6 | startCharacter: Int, 7 | end: Int, 8 | endLine: Int, 9 | endCharacter: Int, 10 | ) 11 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/exceptions/ReflectionException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic.exceptions 2 | 3 | import java.lang.reflect.InvocationTargetException 4 | 5 | object ReflectionException { 6 | def unapply(e: Throwable): Option[Throwable] = Some(flatten(e)) 7 | 8 | def flatten(e: Throwable): Throwable = e match { 9 | case e: InvocationTargetException => e.getCause 10 | case _ => e 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/exceptions/VersionMismatch.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic.exceptions 2 | 3 | case class VersionMismatch(obtainedVersion: String, expectedVersion: String) 4 | extends Exception( 5 | s"Scalafmt version mismatch. Version in .scalafmt.conf is '$obtainedVersion' and running version is '$expectedVersion'.", 6 | ) 7 | -------------------------------------------------------------------------------- /scalafmt-dynamic/jvm/src/main/scala/org/scalafmt/dynamic/package.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | package object dynamic { 4 | 5 | private[dynamic] type FormatEval[T] = Either[ScalafmtDynamicError, T] 6 | 7 | type FormatResult = FormatEval[String] 8 | 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-dynamic/native/src/test/scala/org/scalafmt/dynamic/DynamicSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic 2 | 3 | import org.scalafmt.interfaces._ 4 | 5 | import munit.FunSuite 6 | 7 | class DynamicSuite extends FunSuite { 8 | 9 | test("Scalafmt interface")( 10 | interceptMessage[ScalafmtException]( 11 | "Can't use different version for native CLI", 12 | )(Scalafmt.create(this.getClass.getClassLoader)), 13 | ) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-dynamic/shared/src/main/scala/org/scalafmt/dynamic/exceptions/ScalafmtException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.dynamic.exceptions 2 | 3 | import org.scalafmt.interfaces 4 | 5 | import scala.util.control.NoStackTrace 6 | 7 | case class ScalafmtException(message: String, cause: Throwable) 8 | extends interfaces.ScalafmtException(message, cause) with NoStackTrace 9 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/PositionException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | import java.nio.file.Path 4 | 5 | /** An exception that happened at a position in a source file such as a parse 6 | * error. 7 | */ 8 | abstract class PositionException(message: String, cause: Throwable) 9 | extends Exception(message, cause) { 10 | 11 | override def fillInStackTrace(): Throwable = synchronized(this) 12 | 13 | /** @return 14 | * The file where the error occurred. 15 | */ 16 | def file(): Path 17 | 18 | /** @return 19 | * The text contents of the file being formatted. 20 | */ 21 | def code(): String 22 | 23 | /** @return 24 | * The fully formatted error message including line content and caret. 25 | */ 26 | def longMessage(): String 27 | 28 | /** @return 29 | * Only the error message itself without line content and caret. 30 | */ 31 | def shortMessage(): String 32 | 33 | def startLine(): Int 34 | def startCharacter(): Int 35 | def endLine(): Int 36 | def endCharacter(): Int 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/RepositoryCredential.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | final class RepositoryCredential( 4 | val host: String, 5 | val username: String, 6 | val password: String, 7 | ) 8 | 9 | object RepositoryCredential { 10 | trait ScalafmtExtension { 11 | def withRepositoryCredentials(credentials: RepositoryCredential*): Scalafmt 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/ScalafmtClassLoader.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | /** A classloader that shares only scalafmt-interfaces classes from the parent 4 | * classloader. 5 | * 6 | * This classloader is intended to be used as a parent when class-loading 7 | * scalafmt-dynamic. By using this classloader as a parent, it's possible to 8 | * cast runtime instances from the scalafmt-dynamic classloader into 9 | * `org.scalafmt.interfaces.Scalafmt` from this classloader. 10 | */ 11 | class ScalafmtClassLoader(val parent: ClassLoader) extends ClassLoader(null) { 12 | @throws[ClassNotFoundException] 13 | override protected def findClass(name: String): Class[_] = 14 | if (name.startsWith("org.scalafmt.interfaces")) parent.loadClass(name) 15 | else super.findClass(name) 16 | } 17 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/ScalafmtException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | class ScalafmtException(message: String, cause: Throwable) 4 | extends RuntimeException(message, cause, true, false) 5 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/ScalafmtResult.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | final class ScalafmtResult(val value: String, val exception: Throwable) { 4 | def this(value: String) = this(value, null) 5 | def this(exception: Throwable) = this(null, exception) 6 | } 7 | -------------------------------------------------------------------------------- /scalafmt-interfaces/js/src/main/scala/org/scalafmt/interfaces/ScalafmtSessionFactory.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | import java.nio.file.Path 4 | 5 | trait ScalafmtSessionFactory { 6 | 7 | /** Create a ScalafmtSession to format a batch of files using fixed 8 | * configuration. 9 | * @param config 10 | * location of the configuration file 11 | * @return 12 | * a new session instance 13 | */ 14 | def createSession(config: Path): ScalafmtSession 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/PositionException.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | import java.nio.file.Path; 4 | 5 | /** 6 | * An exception that happened at a position in a source file such as a parse error. 7 | */ 8 | abstract public class PositionException extends Exception { 9 | public PositionException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | @Override 14 | public synchronized Throwable fillInStackTrace() { 15 | return this; 16 | } 17 | 18 | /** 19 | * @return The file where the error occurred. 20 | */ 21 | public abstract Path file(); 22 | 23 | /** 24 | * @return The text contents of the file being formatted. 25 | */ 26 | public abstract String code(); 27 | 28 | /** 29 | * @return The fully formatted error message including line content and caret. 30 | */ 31 | public abstract String longMessage(); 32 | 33 | /** 34 | * @return Only the error message itself without line content and caret. 35 | */ 36 | public abstract String shortMessage(); 37 | 38 | public abstract int startLine(); 39 | public abstract int startCharacter(); 40 | public abstract int endLine(); 41 | public abstract int endCharacter(); 42 | } 43 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/RepositoryCredential.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | public final class RepositoryCredential { 4 | public final String host; 5 | public final String username; 6 | public final String password; 7 | 8 | public RepositoryCredential(String host, String username, String password) { 9 | this.host = host; 10 | this.username = username; 11 | this.password = password; 12 | } 13 | 14 | public interface ScalafmtExtension { 15 | Scalafmt withRepositoryCredentials(RepositoryCredential... credentials); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/ScalafmtClassLoader.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | /** 4 | * A classloader that shares only scalafmt-interfaces classes from the parent classloader. 5 | * 6 | * This classloader is intended to be used as a parent when class-loading scalafmt-dynamic. 7 | * By using this classloader as a parent, it's possible to cast runtime instances from 8 | * the scalafmt-dynamic classloader into `org.scalafmt.interfaces.Scalafmt` from this classloader. 9 | */ 10 | public class ScalafmtClassLoader extends ClassLoader { 11 | 12 | private ClassLoader parent; 13 | public ScalafmtClassLoader(ClassLoader parent) { 14 | super(null); 15 | this.parent = parent; 16 | } 17 | 18 | @Override 19 | protected Class findClass(String name) throws ClassNotFoundException { 20 | if (name.startsWith("org.scalafmt.interfaces")) { 21 | return parent.loadClass(name); 22 | } else { 23 | return super.findClass(name); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/ScalafmtException.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | public class ScalafmtException extends RuntimeException { 4 | 5 | public ScalafmtException(String message, Throwable cause) { 6 | super(message, cause, true, false); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/ScalafmtResult.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | public final class ScalafmtResult { 4 | public final String value; 5 | public final Throwable exception; 6 | 7 | public ScalafmtResult(String value) { 8 | this.value = value; 9 | this.exception = null; 10 | } 11 | 12 | public ScalafmtResult(Throwable exception) { 13 | this.exception = exception; 14 | this.value = null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scalafmt-interfaces/jvm/src/main/java/org/scalafmt/interfaces/ScalafmtSessionFactory.java: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces; 2 | 3 | import java.nio.file.Path; 4 | 5 | public interface ScalafmtSessionFactory { 6 | 7 | /** 8 | * Create a ScalafmtSession to format a batch of files using fixed configuration. 9 | * @param config location of the configuration file 10 | * @return a new session instance 11 | */ 12 | ScalafmtSession createSession(Path config); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/PositionException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | import java.nio.file.Path 4 | 5 | /** An exception that happened at a position in a source file such as a parse 6 | * error. 7 | */ 8 | abstract class PositionException(message: String, cause: Throwable) 9 | extends Exception(message, cause) { 10 | 11 | override def fillInStackTrace(): Throwable = synchronized(this) 12 | 13 | /** @return 14 | * The file where the error occurred. 15 | */ 16 | def file(): Path 17 | 18 | /** @return 19 | * The text contents of the file being formatted. 20 | */ 21 | def code(): String 22 | 23 | /** @return 24 | * The fully formatted error message including line content and caret. 25 | */ 26 | def longMessage(): String 27 | 28 | /** @return 29 | * Only the error message itself without line content and caret. 30 | */ 31 | def shortMessage(): String 32 | 33 | def startLine(): Int 34 | def startCharacter(): Int 35 | def endLine(): Int 36 | def endCharacter(): Int 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/RepositoryCredential.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | final class RepositoryCredential( 4 | val host: String, 5 | val username: String, 6 | val password: String, 7 | ) 8 | 9 | object RepositoryCredential { 10 | trait ScalafmtExtension { 11 | def withRepositoryCredentials(credentials: RepositoryCredential*): Scalafmt 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/ScalafmtClassLoader.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | /** A classloader that shares only scalafmt-interfaces classes from the parent 4 | * classloader. 5 | * 6 | * This classloader is intended to be used as a parent when class-loading 7 | * scalafmt-dynamic. By using this classloader as a parent, it's possible to 8 | * cast runtime instances from the scalafmt-dynamic classloader into 9 | * `org.scalafmt.interfaces.Scalafmt` from this classloader. 10 | */ 11 | class ScalafmtClassLoader(val parent: ClassLoader) extends ClassLoader(null) { 12 | @throws[ClassNotFoundException] 13 | override protected def findClass(name: String): Class[_] = 14 | if (name.startsWith("org.scalafmt.interfaces")) parent.loadClass(name) 15 | else super.findClass(name) 16 | } 17 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/ScalafmtException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | class ScalafmtException(message: String, cause: Throwable) 4 | extends RuntimeException(message, cause, true, false) 5 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/ScalafmtResult.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | final class ScalafmtResult(val value: String, val exception: Throwable) { 4 | def this(value: String) = this(value, null) 5 | def this(exception: Throwable) = this(null, exception) 6 | } 7 | -------------------------------------------------------------------------------- /scalafmt-interfaces/native/src/main/java/org/scalafmt/interfaces/ScalafmtSessionFactory.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.interfaces 2 | 3 | import java.nio.file.Path 4 | 5 | trait ScalafmtSessionFactory { 6 | 7 | /** Create a ScalafmtSession to format a batch of files using fixed 8 | * configuration. 9 | * @param config 10 | * location of the configuration file 11 | * @return 12 | * a new session instance 13 | */ 14 | def createSession(config: Path): ScalafmtSession 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-macros/shared/src/main/scala/org/scalafmt/config/DialectMacro.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import scala.meta.Dialect 4 | 5 | import scala.language.experimental.macros 6 | import scala.reflect.macros.blackbox 7 | 8 | // Builds a map between string (the scalafmt method name) 9 | // and dialect method application 10 | private[scalafmt] object DialectMacro { 11 | def dialectMap: Map[String, ((Dialect, Any) => Dialect)] = 12 | macro dialectMap_impl 13 | 14 | def dialectMap_impl( 15 | c: blackbox.Context, 16 | ): c.Expr[Map[String, ((Dialect, Any) => Dialect)]] = { 17 | import c.universe._ 18 | val methods = typeOf[Dialect].members.flatMap { 19 | case v: MethodSymbol => v.paramLists match { 20 | case (param :: Nil) :: Nil => // single parameter 21 | val methodName = v.name 22 | val methodNameStr = methodName.toString 23 | if (methodNameStr.startsWith("with")) { 24 | val tpe = param.typeSignature 25 | Some(q"$methodNameStr -> ((dialect: scala.meta.Dialect, v: Any) => dialect.$methodName(v.asInstanceOf[$tpe]))") 26 | } else None 27 | case _ => None 28 | } 29 | case _ => None 30 | } 31 | c.Expr[Map[String, ((Dialect, Any) => Dialect)]]( 32 | q"""scala.collection.immutable.Map(..$methods)""", 33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /scalafmt-sysops/js/src/main/scala-2.13/org/scalafmt/CollectionConverters.scala: -------------------------------------------------------------------------------- 1 | package scala.collection.parallel 2 | 3 | object CollectionConverters { 4 | implicit class XtensionIterable[T](val col: Iterable[T]) extends AnyVal { 5 | def par = col 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scalafmt-sysops/js/src/main/scala/org/scalafmt/sysops/PlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | private[scalafmt] object PlatformCompat { 4 | def isJS = true 5 | def isJVM = false 6 | def isScalaNative = false 7 | def isNativeOnWindows = false 8 | 9 | def relativize(cwd: AbsoluteFile, file: AbsoluteFile): String = { 10 | val path = file.toString 11 | val cwdStr = cwd.toString 12 | if (path.startsWith(cwdStr)) path.substring(cwdStr.length + 1) else path 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-sysops/js/src/test/scala/org/scalafmt/sysops/DeleteTree.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import java.nio.file.Path 4 | 5 | object DeleteTree { 6 | def apply(path: Path): Unit = PlatformFileOps 7 | .rmdir(path = path.toString, recursive = true, force = true) 8 | } 9 | -------------------------------------------------------------------------------- /scalafmt-sysops/jvm-native/src/main/scala/org/scalafmt/sysops/PlatformPathMatcher.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import java.nio.file 4 | 5 | object PlatformPathMatcher { 6 | val fs: file.FileSystem = file.FileSystems.getDefault 7 | 8 | def apply(pattern: String): PathMatcher = { 9 | try fs.getPathMatcher(pattern) 10 | catch { 11 | case e: IllegalArgumentException => 12 | val sb = new StringBuilder() 13 | sb.append("Invalid path matcher pattern: ").append(pattern) 14 | val err = e.getMessage 15 | if (null != err && err.nonEmpty) sb.append("; ").append(err) 16 | throw new ScalafmtSysException(sb.toString()) 17 | } 18 | }.matches 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-sysops/jvm-native/src/test/scala/org/scalafmt/sysops/DeleteTree.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import java.io.IOException 4 | import java.nio.file._ 5 | 6 | object DeleteTree { 7 | def apply(path: Path): Unit = { 8 | Files.walkFileTree(path, new DeleteTree) 9 | () 10 | } 11 | } 12 | 13 | class DeleteTree extends FileVisitor[Path] { 14 | override def preVisitDirectory( 15 | dir: Path, 16 | attrs: attribute.BasicFileAttributes, 17 | ): FileVisitResult = FileVisitResult.CONTINUE 18 | 19 | override def visitFile( 20 | file: Path, 21 | attrs: attribute.BasicFileAttributes, 22 | ): FileVisitResult = { 23 | util.Try(Files.delete(file)) 24 | FileVisitResult.CONTINUE 25 | } 26 | 27 | override def visitFileFailed(file: Path, exc: IOException): FileVisitResult = 28 | throw exc 29 | 30 | override def postVisitDirectory( 31 | dir: Path, 32 | exc: IOException, 33 | ): FileVisitResult = { 34 | util.Try(Files.delete(dir)) 35 | FileVisitResult.CONTINUE 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-sysops/jvm/src/main/scala/org/scalafmt/sysops/PlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | private[scalafmt] object PlatformCompat { 4 | def isJS = false 5 | def isJVM = true 6 | def isScalaNative = false 7 | def isNativeOnWindows = false 8 | 9 | def relativize(cwd: AbsoluteFile, file: AbsoluteFile): String = cwd.toUri 10 | .relativize(file.toUri).toString 11 | } 12 | -------------------------------------------------------------------------------- /scalafmt-sysops/native/src/main/scala/org/scalafmt/sysops/GranularPlatformAsyncOps.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import java.nio.file.Path 4 | 5 | import scala.concurrent.Future 6 | import scala.io.Codec 7 | 8 | private[sysops] object GranularPlatformAsyncOps { 9 | 10 | def readFileAsync(path: Path)(implicit codec: Codec): Future[String] = 11 | Future(PlatformFileOps.readFile(path))(PlatformRunOps.inputExecutionContext) 12 | 13 | def writeFileAsync(path: Path, data: String)(implicit 14 | codec: Codec, 15 | ): Future[Unit] = Future( 16 | PlatformFileOps.writeFile(path, data), 17 | )(PlatformRunOps.outputExecutionContext) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-sysops/native/src/main/scala/org/scalafmt/sysops/PlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import scala.scalanative.runtime.Platform 4 | 5 | private[scalafmt] object PlatformCompat { 6 | def isJS = false 7 | def isJVM = false 8 | def isScalaNative = true 9 | def isNativeOnWindows = Platform.isWindows() 10 | 11 | def relativize(cwd: AbsoluteFile, file: AbsoluteFile): String = { 12 | val usePath = PlatformCompat.isNativeOnWindows 13 | if (usePath) cwd.path.relativize(file.path).toString 14 | else cwd.toUri.relativize(file.toUri).toString 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala-2.12/org/scalafmt/CompatCollections.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | private[scalafmt] object CompatCollections { 4 | val JavaConverters = scala.collection.JavaConverters 5 | } 6 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala-2.12/org/scalafmt/sysops/GranularDialectAsyncOps.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import scala.concurrent.ExecutionContext 4 | import scala.concurrent.ExecutionContextExecutor 5 | 6 | private[sysops] object GranularDialectAsyncOps { 7 | 8 | object parasiticExecutionContext extends ExecutionContextExecutor { 9 | override final def execute(runnable: Runnable): Unit = runnable.run() 10 | override final def reportFailure(t: Throwable): Unit = ExecutionContext 11 | .defaultReporter(t) 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala-2.13/org/scalafmt/CompatCollections.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | private[scalafmt] object CompatCollections { 4 | val JavaConverters = scala.jdk.CollectionConverters 5 | } 6 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala-2.13/org/scalafmt/sysops/GranularDialectAsyncOps.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import scala.concurrent.ExecutionContext 4 | 5 | private[sysops] object GranularDialectAsyncOps { 6 | 7 | def parasiticExecutionContext: ExecutionContext.parasitic.type = 8 | ExecutionContext.parasitic 9 | 10 | } 11 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/FileStat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | trait FileStat { 4 | 5 | def isDirectory: Boolean 6 | def isRegularFile: Boolean 7 | def isSymlink: Boolean 8 | 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/OsSpecific.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | /** Utils related to differences between various operating systems. */ 4 | object OsSpecific { 5 | def isWindows: Boolean = 6 | // NOTE: org.scalameta:io implements java.io.File for Node.js so this will work correctly 7 | // on Node.js + Window and also in the browser. 8 | java.io.File.separatorChar == '\\' 9 | 10 | // We need double backslashes here because Regex needs to be escaped. 11 | def fixSeparatorsInPathPattern(unixSpecificPattern: String): String = 12 | if (isWindows) unixSpecificPattern.replace("/", "\\\\") 13 | else unixSpecificPattern 14 | 15 | def inPathMatcherForm(str: String): String = 16 | if (PlatformCompat.isNativeOnWindows) str.replace("\\\\", "/") 17 | else fixSeparatorsInPathPattern(str) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/PathMatcher.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | import java.nio.file.Path 4 | import java.util.regex.Pattern 5 | 6 | trait PathMatcher { 7 | def matches(path: Path): Boolean 8 | } 9 | 10 | object PathMatcher { 11 | 12 | class Regex(pattern: Pattern) extends PathMatcher { 13 | def matches(path: Path): Boolean = pattern.matcher(path.toString).find() 14 | } 15 | 16 | object Regex { 17 | def apply(regex: String): Regex = 18 | try new Regex(Pattern.compile(regex)) 19 | catch { 20 | case e: Throwable => 21 | val msg = s"Invalid path patcher regex: /$regex/; ${e.getMessage}" 22 | throw new ScalafmtSysException(msg) 23 | } 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/ScalafmtSysException.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.sysops 2 | 3 | class ScalafmtSysException(e: String) extends Exception(e) 4 | -------------------------------------------------------------------------------- /scalafmt-tests-community/common/shared/src/test/scala/org/scalafmt/community/common/CommunityBuild.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.common 2 | 3 | import org.scalafmt.config.ConfParsed 4 | 5 | import scala.meta._ 6 | 7 | import java.nio.file._ 8 | 9 | import metaconfig.Conf 10 | 11 | case class CommunityBuild( 12 | giturl: String, 13 | commit: String, 14 | name: String, 15 | excluded: List[String], 16 | checkedFiles: Int, 17 | dialect: sourcecode.Text[Dialect], 18 | styles: Set[String] = Set.empty, 19 | stylesIncluded: Boolean = true, 20 | fileOverride: Option[String] = null, 21 | statsPerStyle: Map[String, TestStats.Style] = Map.empty, 22 | statsAllStyles: Option[TestStats.Style] = None, 23 | ) { 24 | private val excludedMatchers = { 25 | val fs = FileSystems.getDefault 26 | excluded.map(fs.getPathMatcher) 27 | } 28 | 29 | def isExcluded(path: Path): Boolean = excludedMatchers 30 | .exists(p => p.matches(path)) 31 | 32 | val fileOverrideConf = fileOverride 33 | .map(x => ConfParsed.fromString(x).conf.get.asInstanceOf[Conf.Obj]) 34 | } 35 | -------------------------------------------------------------------------------- /scalafmt-tests-community/common/shared/src/test/scala/org/scalafmt/community/common/CommunityRepoSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.common 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityRepoSuite(giturl: String, name: String) 8 | extends CommunitySuite { 9 | 10 | protected def getBuild( 11 | ref: String, 12 | dialect: sourcecode.Text[Dialect], 13 | files: Int, 14 | excluded: List[String] = Nil, 15 | fileOverride: String = null, 16 | styles: Seq[sourcecode.Text[ScalafmtConfig]] = Seq.empty, 17 | statsPerStyle: Map[String, TestStats.Style] = Map.empty, 18 | statsAllStyles: Option[TestStats.Style] = None, 19 | stylesIncluded: Boolean = true, 20 | ) = CommunityBuild( 21 | giturl, 22 | ref, 23 | name, 24 | excluded, 25 | files, 26 | dialect, 27 | styles = styles.map(_.source).map(x => x.substring(1 + x.lastIndexOf('.'))) 28 | .toSet, 29 | fileOverride = Option(fileOverride), 30 | statsPerStyle = statsPerStyle, 31 | statsAllStyles = statsAllStyles, 32 | stylesIncluded = stylesIncluded, 33 | ) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /scalafmt-tests-community/common/shared/src/test/scala/org/scalafmt/community/common/TestStats.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.common 2 | 3 | case class TestStats( 4 | checkedFiles: Int, 5 | errors: Int, 6 | lastError: Option[Throwable], 7 | timeTaken: Long, 8 | linesParsed: Int, 9 | ) 10 | 11 | object TestStats { 12 | final val init = TestStats(0, 0, None, 0, 0) 13 | 14 | def merge(s1: TestStats, s2: TestStats): TestStats = TestStats( 15 | s1.checkedFiles + s2.checkedFiles, 16 | s1.errors + s2.errors, 17 | s1.lastError.orElse(s2.lastError), 18 | s1.timeTaken + s2.timeTaken, 19 | s1.linesParsed + s2.linesParsed, 20 | ) 21 | 22 | case class Style(expectedStatesVisited: Int) 23 | } 24 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityAkkaSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityAkkaSuite(name: String) 8 | extends CommunityRepoSuite("https://github.com/akka/akka.git", name) 9 | 10 | class CommunityAkka_2_9_Suite extends CommunityAkkaSuite("akka-2.9") { 11 | 12 | override protected def builds = Seq(getBuild( 13 | "v2.9.6", 14 | dialects.Scala213, 15 | 1401, 16 | excluded = "glob:**/scripts/*" :: Nil, 17 | )) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityMunitSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | class CommunityMunitSuite 8 | extends CommunityRepoSuite("https://github.com/scalameta/munit.git", "munit") { 9 | 10 | override protected def builds = Seq(getBuild("v1.0.1", dialects.Scala213, 109)) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityPlayFrameworkSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityPlayFrameworkSuite(name: String) 8 | extends CommunityRepoSuite( 9 | "https://github.com/playframework/playframework.git", 10 | name, 11 | ) 12 | 13 | class CommunityPlayFramework_3_0_Suite 14 | extends CommunityPlayFrameworkSuite("playframework-3.0") { 15 | 16 | override protected def builds = Seq(getBuild("3.0.5", dialects.Scala213, 454)) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityScalaCliSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityScalaCliSuite(name: String) 8 | extends CommunityRepoSuite( 9 | "https://github.com/VirtusLab/scala-cli.git", 10 | name, 11 | ) 12 | 13 | class CommunityScalaCli1_5Suite 14 | extends CommunityScalaCliSuite("scala-cli-1.5") { 15 | 16 | override protected def builds = Seq(getBuild("v1.5.0", dialects.Scala30, 589)) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityScalaJsSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityScalaJsSuite(name: String) 8 | extends CommunityRepoSuite("https://github.com/scala-js/scala-js.git", name) 9 | 10 | class CommunityScalaJs1_17Suite extends CommunityScalaJsSuite("scala-js-1.17") { 11 | 12 | override protected def builds = Seq(getBuild("v1.17.0", dialects.Scala213, 787)) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityScalazSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityScalazSuite(name: String) 8 | extends CommunityRepoSuite("https://github.com/scalaz/scalaz.git", name) 9 | 10 | class CommunityScalaz_7_3_Suite extends CommunityScalazSuite("scalaz-7.3") { 11 | 12 | override protected def builds = Seq(getBuild("v7.3.8", dialects.Scala213, 420)) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-tests-community/other/shared/src/test/scala/org/scalafmt/community/other/CommunityZioSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.other 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityZioSuite(name: String) 8 | extends CommunityRepoSuite("https://github.com/zio/zio.git", name) 9 | 10 | class CommunityZio_2_1_Suite extends CommunityZioSuite("zio-2.1") { 11 | 12 | override protected def builds = Seq(getBuild("v2.1.9", dialects.Scala213, 453)) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-tests-community/scala2/shared/src/test/scala/org/scalafmt/community/scala2/CommunityScala2Suite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.scala2 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityScala2Suite(name: String) 8 | extends CommunityRepoSuite("https://github.com/scala/scala.git", name) 9 | 10 | class CommunityScala2_12Suite extends CommunityScala2Suite("scala-2.12") { 11 | 12 | override protected def totalStatesVisited: Option[Int] = Some(42546299) 13 | 14 | override protected def builds = 15 | Seq(getBuild("v2.12.20", dialects.Scala212, 1277)) 16 | 17 | } 18 | 19 | class CommunityScala2_13Suite extends CommunityScala2Suite("scala-2.13") { 20 | 21 | override protected def totalStatesVisited: Option[Int] = Some(52667390) 22 | 23 | override protected def builds = 24 | Seq(getBuild("v2.13.14", dialects.Scala213, 1287)) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /scalafmt-tests-community/scala3/shared/src/test/scala/org/scalafmt/community/scala3/CommunityScala3Suite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.scala3 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunityScala3Suite(name: String) 8 | extends CommunityRepoSuite("https://github.com/scala/scala3.git", name) 9 | 10 | class CommunityScala3_2Suite extends CommunityScala3Suite("scala-3.2") { 11 | 12 | override protected def totalStatesVisited: Option[Int] = Some(39186772) 13 | 14 | override protected def builds = Seq(getBuild("3.2.2", dialects.Scala32, 791)) 15 | 16 | } 17 | 18 | class CommunityScala3_3Suite extends CommunityScala3Suite("scala-3.3") { 19 | 20 | override protected def totalStatesVisited: Option[Int] = Some(42290938) 21 | 22 | override protected def builds = Seq(getBuild("3.3.3", dialects.Scala33, 861)) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /scalafmt-tests-community/spark/shared/src/test/scala/org/scalafmt/community/spark/CommunitySparkSuite.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.community.spark 2 | 3 | import org.scalafmt.community.common.CommunityRepoSuite 4 | 5 | import scala.meta._ 6 | 7 | abstract class CommunitySparkSuite(name: String) 8 | extends CommunityRepoSuite("https://github.com/apache/spark.git", name) 9 | 10 | class CommunitySpark3_4Suite extends CommunitySparkSuite("spark-3.4") { 11 | 12 | override protected def totalStatesVisited: Option[Int] = Some(85923242) 13 | 14 | override protected def builds = Seq(getBuild("v3.4.1", dialects.Scala213, 2585)) 15 | 16 | } 17 | 18 | class CommunitySpark3_5Suite extends CommunitySparkSuite("spark-3.5") { 19 | 20 | override protected def totalStatesVisited: Option[Int] = Some(90889429) 21 | 22 | override protected def builds = Seq(getBuild("v3.5.3", dialects.Scala213, 2756)) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /scalafmt-tests/js/src/test/scala/org/scalafmt/TestPlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.concurrent._ 4 | 5 | object TestPlatformCompat { 6 | def executeAndWait(body: => Unit)(timeoutSeconds: Option[Int]): Unit = 7 | // we don't wait in scala.js 8 | Future(body)(scala.scalajs.concurrent.JSExecutionContext.queue) 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-tests/jvm/src/test/scala-2.12/org.scalafmt/TestCompatCollections.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | private[scalafmt] object TestCompatCollections { 4 | object ParConverters 5 | } 6 | -------------------------------------------------------------------------------- /scalafmt-tests/jvm/src/test/scala-2.13/org/scalafmt/TestCompatCollections.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | private[scalafmt] object TestCompatCollections { 4 | val ParConverters = scala.collection.parallel.CollectionConverters 5 | } 6 | -------------------------------------------------------------------------------- /scalafmt-tests/jvm/src/test/scala/org/scalafmt/TestPlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.concurrent._ 4 | 5 | object TestPlatformCompat { 6 | def executeAndWait(body: => Unit)(timeoutSeconds: Option[Int]): Unit = { 7 | val future = Future(body)(ExecutionContext.Implicits.global) 8 | timeoutSeconds 9 | .foreach(x => Await.ready(future, duration.Duration(x, duration.SECONDS))) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scalafmt-tests/native/src/test/scala/org/scalafmt/TestPlatformCompat.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.concurrent._ 4 | 5 | object TestPlatformCompat { 6 | def executeAndWait(body: => Unit)(timeoutSeconds: Option[Int]): Unit = { 7 | val future = Future(body)(ExecutionContext.Implicits.global) 8 | timeoutSeconds 9 | .foreach(x => Await.ready(future, duration.Duration(x, duration.SECONDS))) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/Test.manual: -------------------------------------------------------------------------------- 1 | SKIP https://raw.githubusercontent.com/akka/akka/3698928fbdaa8fef8e2037fbc51887ab60addefb/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala 2 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/BeforeCommentWithinMethodChain.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 40 2 | <<< keep indentation for comments within method chain in statement 3 | foo() 4 | // bar 5 | // baz 6 | .bar() 7 | >>> 8 | foo() 9 | // bar 10 | // baz 11 | .bar() 12 | <<< keep indentation for comments within method chain in assignment 13 | val res = foo() 14 | // bar 15 | // baz 16 | .bar() 17 | >>> 18 | val res = foo() 19 | // bar 20 | // baz 21 | .bar() 22 | <<< don't add extra indentation for comments in middle of chain 23 | "x" 24 | // bar 25 | // baz 26 | .bar() 27 | // bar2 28 | // baz2 29 | .bar2() 30 | >>> 31 | "x" 32 | // bar 33 | // baz 34 | .bar() 35 | // bar2 36 | // baz2 37 | .bar2() 38 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/MixedTokens.stat: -------------------------------------------------------------------------------- 1 | preset = defaultWithAlign 2 | align.tokenCategory { 3 | Equals = Assign 4 | LeftArrow = Assign 5 | } 6 | <<< #883 7 | for { 8 | a <- b 9 | cc = d 10 | } yield cc 11 | >>> 12 | for { 13 | a <- b 14 | cc = d 15 | } yield cc 16 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/NoSpace.stat: -------------------------------------------------------------------------------- 1 | align.tokens = [":", ","] 2 | <<< align colons 3 | def foo( 4 | a: Int, 5 | aa: Int 6 | ): Unit 7 | >>> 8 | def foo( 9 | a: Int, 10 | aa: Int 11 | ): Unit 12 | <<< align commas 13 | { 14 | foo(a, b, c) 15 | foo(aa, bb, c) 16 | } 17 | >>> 18 | { 19 | foo(a, b, c) 20 | foo(aa, bb, c) 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/TrollAlignment.stat: -------------------------------------------------------------------------------- 1 | preset = defaultWithAlign 2 | align.treeCategory { 3 | Case: Assign 4 | "Enumerator.Generator": Assign 5 | } 6 | align.tokenCategory { 7 | LeftArrow = Assign 8 | RightArrow = Assign 9 | } 10 | <<< troll 11 | { 12 | x match { case 1 => 2 } 13 | for { a <- b } yield b 14 | } 15 | >>> 16 | { 17 | x match { case 1 => 2 } 18 | for { a <- b } yield b 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/addSbtPlugin.source: -------------------------------------------------------------------------------- 1 | preset = defaultWithAlign 2 | runner.dialect = Sbt0137 3 | <<< align addSbtPlugin 4 | addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M14") 5 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") 6 | addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.14") 7 | >>> 8 | addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M14") 9 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3") 10 | addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.14") 11 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/comment-wrapping.source: -------------------------------------------------------------------------------- 1 | preset = defaultWithAlign 2 | runner.dialect = Sbt0137 3 | align.openParenCallSite = true 4 | danglingParentheses.preset = false 5 | <<< wrap with inline comment 6 | lazy val ivyProj = (project in file("ivy")) 7 | .dependsOn(interfaceProj, 8 | crossProj, 9 | logProj % "compile;test->test", 10 | ioProj % "compile;test->test", /*launchProj % "test->test",*/ collectionProj) 11 | >>> 12 | lazy val ivyProj = (project in file("ivy")) 13 | .dependsOn(interfaceProj, 14 | crossProj, 15 | logProj % "compile;test->test", 16 | ioProj % "compile;test->test", 17 | /*launchProj % "test->test",*/ collectionProj) 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/defaultTokenOwners.stat: -------------------------------------------------------------------------------- 1 | align.tokens."+" = ["="] 2 | <<< don't align independent columns (see #1896) 3 | object fmt { 4 | val header = JwtHeader(algorithm = Some(JwtAlgorithm.HMD5)) 5 | val content = payload.toString 6 | val claim = JwtClaim(content = content) 7 | } 8 | >>> 9 | object fmt { 10 | val header = JwtHeader(algorithm = Some(JwtAlgorithm.HMD5)) 11 | val content = payload.toString 12 | val claim = JwtClaim(content = content) 13 | } 14 | <<< respect specified owner 15 | align.tokens."+" = [{code = "=", owner = "(Term.Assign|Defn.Val)"}] 16 | === 17 | object fmt { 18 | val header = JwtHeader(algorithm = Some(JwtAlgorithm.HMD5)) 19 | val content = payload.toString 20 | val claim = JwtClaim(content = content) 21 | } 22 | >>> 23 | object fmt { 24 | val header = JwtHeader(algorithm = Some(JwtAlgorithm.HMD5)) 25 | val content = payload.toString 26 | val claim = JwtClaim(content = content) 27 | } 28 | <<< fallback to any owner 29 | align.tokens."+" = ["!"] 30 | === 31 | object fmt { 32 | aaa ! 2 33 | bb ! 3 34 | } 35 | >>> 36 | object fmt { 37 | aaa ! 2 38 | bb ! 3 39 | } 40 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/align/duplicateAlign.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 20 2 | align.tokens = most 3 | <<< #1202 4 | { 5 | foo(aaaaaaaa, bbbbb) 6 | val x = 2 7 | val xx = 2 8 | } 9 | >>> 10 | { 11 | foo( 12 | aaaaaaaa, 13 | bbbbb 14 | ) 15 | val x = 2 16 | val xx = 2 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/binPack/LambdaParameterFalse.stat: -------------------------------------------------------------------------------- 1 | style=default 2 | <<< weird line break 3 | class A {{{{ 4 | def streamRequestEntity(creator: (Source[ParserOutput.RequestOutput, 5 | NotUsed]) => RequestEntity): R = 1 6 | }}}} 7 | >>> 8 | class A { 9 | { 10 | { 11 | { 12 | def streamRequestEntity( 13 | creator: ( 14 | Source[ParserOutput.RequestOutput, NotUsed] 15 | ) => RequestEntity 16 | ): R = 1 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/binPack/LiteralListNoByte.stat: -------------------------------------------------------------------------------- 1 | binPack.literalArgumentLists = true 2 | binPack.literalsExclude = ["Byte"] 3 | <<< byte 4 | literals.hexDigits=unchanged 5 | === 6 | val secret: List[Bit] = List(0xB5,0xB5,0x2F,0x2F,0x2F,0xB5,0x2F,0xB5,0x2F,0x2F,0x2F,0xB5,0xB5,0x2F,0x2F,0xB5,0x2F,0xB5,0xB5,0x2F,0x2F,0xB5,0x2F,0xB5,0x2F,0x2F,0xB5,0xB5,0x2F,0x2F,0x2F,0x2F,0x2F,0xB5,0x2F,0xB5,0x2F,0x2F,0xB5,0xB5,0xB5,0xB5,0x2F,0xB5,0x2F,0x2F,0x2F,0xB5,0xB5,0x2F,0xB5,0xB5,0x2F,0xB5,0xB5,0xB5,0x2F,0xB5,0xB5,0xB5,0x2F,0xB5,1) 7 | >>> 8 | val secret: List[Bit] = List( 9 | 0xB5, 10 | 0xB5, 11 | 0x2F, 12 | 0x2F, 13 | 0x2F, 14 | 0xB5, 15 | 0x2F, 16 | 0xB5, 17 | 0x2F, 18 | 0x2F, 19 | 0x2F, 20 | 0xB5, 21 | 0xB5, 22 | 0x2F, 23 | 0x2F, 24 | 0xB5, 25 | 0x2F, 26 | 0xB5, 27 | 0xB5, 28 | 0x2F, 29 | 0x2F, 30 | 0xB5, 31 | 0x2F, 32 | 0xB5, 33 | 0x2F, 34 | 0x2F, 35 | 0xB5, 36 | 0xB5, 37 | 0x2F, 38 | 0x2F, 39 | 0x2F, 40 | 0x2F, 41 | 0x2F, 42 | 0xB5, 43 | 0x2F, 44 | 0xB5, 45 | 0x2F, 46 | 0x2F, 47 | 0xB5, 48 | 0xB5, 49 | 0xB5, 50 | 0xB5, 51 | 0x2F, 52 | 0xB5, 53 | 0x2F, 54 | 0x2F, 55 | 0x2F, 56 | 0xB5, 57 | 0xB5, 58 | 0x2F, 59 | 0xB5, 60 | 0xB5, 61 | 0x2F, 62 | 0xB5, 63 | 0xB5, 64 | 0xB5, 65 | 0x2F, 66 | 0xB5, 67 | 0xB5, 68 | 0xB5, 69 | 0x2F, 70 | 0xB5, 71 | 1 72 | ) 73 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/Fidelity.source: -------------------------------------------------------------------------------- 1 | 2 | <<< group id 3 | object ScalaJSGroupID { 4 | 5 | def auto_impl(c: Context { type PrefixType = ScalaJSGroupID })() 6 | : Expr[CrossGroupArtifactID] = { 7 | reify { 8 | } 9 | } 10 | } 11 | >>> 12 | object ScalaJSGroupID { 13 | 14 | def auto_impl(c: Context { type PrefixType = ScalaJSGroupID })() 15 | : Expr[CrossGroupArtifactID] = { 16 | reify {} 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/Fidelity.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< statement starts get newline 3 | { 4 | val lhm = factory.empty[jl.Integer, String] 5 | (0 until 100).foreach(key => lhm.put(key, s"elem $key")) 6 | } 7 | >>> 8 | { 9 | val lhm = factory.empty[jl.Integer, String] 10 | (0 until 100).foreach(key => lhm.put(key, s"elem $key")) 11 | } 12 | <<< negated literal inside () 13 | assertEquals("-50", (-50L).toString) 14 | >>> 15 | assertEquals("-50", (-50L).toString) 16 | <<< literals inside () 17 | assertEquals("-50", (50L).toString) 18 | >>> 19 | assertEquals("-50", (50L).toString) 20 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/Semicolon.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< keep on single line, if possible 3 | indent.main = 4 4 | === 5 | text.charAt(pos) match { 6 | case '<' => handle("<"); prev = pos + 1 7 | case '<' => handle("<"); prev = pos + 1 // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 8 | case '<' => handle("<"); prev = pos + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9 | case '<' => 10 | handle("<"); 11 | prev = pos + 1 // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 12 | } 13 | >>> 14 | text.charAt(pos) match { 15 | case '<' => handle("<"); prev = pos + 1 16 | case '<' => 17 | handle("<"); 18 | prev = pos + 1 // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 19 | case '<' => 20 | handle("<"); 21 | prev = pos + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 22 | case '<' => 23 | handle("<"); 24 | prev = pos + 1 // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 25 | } 26 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/Super.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< #661 super space 3 | foo. super.x() 4 | >>> 5 | foo.super.x() 6 | <<< #679 7 | @enableIf(c => !c.compilerSettings.exists(_.matches("""^-Xplugin:.*scalajs-compiler_[0-9\.\-]*\.jar$"""))) 8 | def javafxTyper[A]: PropertyTyper[A] = macro Macros.javafxTyper[A] 9 | >>> 10 | @enableIf(c => 11 | !c.compilerSettings.exists( 12 | _.matches("""^-Xplugin:.*scalajs-compiler_[0-9\.\-]*\.jar$"""))) 13 | def javafxTyper[A]: PropertyTyper[A] = macro Macros.javafxTyper[A] 14 | <<< #671 15 | def this(a: Int) = { 16 | this 17 | abc()} 18 | >>> 19 | def this(a: Int) = { 20 | this 21 | abc() 22 | } 23 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/TermParam.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< unindent by 2 in blocks, #186 3 | scrut.branchSwitch(scrut.value, 4 | casevals = normalcases.map { case (v, _) => v }, 5 | casefs = normalcases.map { 6 | case (_, body) => genExpr(body, _: Focus) 7 | }) 8 | >>> 9 | scrut.branchSwitch(scrut.value, 10 | casevals = normalcases.map { case (v, _) => v }, 11 | casefs = normalcases.map { case (_, body) => 12 | genExpr(body, _: Focus) 13 | }) 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/default/Unicode.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< preserve the unicode literals in pattern position, see scalafix#619 3 | def a = (1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 } 4 | >>> 5 | def a = (1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 } 6 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/Double.stat: -------------------------------------------------------------------------------- 1 | literals.double = Lower 2 | <<< lowercase 3 | 123.0D 4 | >>> 5 | 123.0d 6 | <<< uppercase 7 | literals.double = Upper 8 | === 9 | 123.0d 10 | >>> 11 | 123.0D 12 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/Float.stat: -------------------------------------------------------------------------------- 1 | literals.float = Lower 2 | <<< lowercase 3 | 123.0F 4 | >>> 5 | 123.0f 6 | <<< uppercase 7 | literals.float = Upper 8 | === 9 | 123.0f 10 | >>> 11 | 123.0F 12 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/Long.stat: -------------------------------------------------------------------------------- 1 | literals.long = Lower 2 | <<< lowercase 3 | 123L 4 | >>> 5 | 123l 6 | <<< uppercase 7 | literals.long = Upper 8 | === 9 | 123l 10 | >>> 11 | 123L 12 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/Unchanged.stat: -------------------------------------------------------------------------------- 1 | literals.long = unchanged 2 | literals.float = unchanged 3 | literals.double = unchanged 4 | <<< long 5 | 1l 6 | >>> 7 | 1l 8 | <<< long ok 9 | 1L 10 | >>> 11 | 1L 12 | <<< float 13 | 1F 14 | >>> 15 | 1F 16 | <<< float ok 17 | 1f 18 | >>> 19 | 1f 20 | <<< double 21 | 1D 22 | >>> 23 | 1D 24 | <<< double ok 25 | 1d 26 | >>> 27 | 1d 28 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/binary.stat: -------------------------------------------------------------------------------- 1 | <<< uppercase l by default 2 | 0b111l 3 | >>> 4 | 0b111L 5 | <<< lowercase l if specified 6 | literals.long = Lower 7 | === 8 | 0b111L 9 | >>> 10 | 0b111l 11 | <<< lowercase 0B by default 12 | 0B111 13 | >>> 14 | 0b111 15 | <<< uppercase 0b if specified 16 | literals.binPrefix = Upper 17 | === 18 | 0b111 19 | >>> 20 | 0B111 21 | <<< change both prefix and suffix 22 | 0B111l 23 | >>> 24 | 0b111L 25 | <<< unchanged 26 | literals.binPrefix = Unchanged 27 | === 28 | 0B111 + 0b111 29 | >>> 30 | 0B111 + 0b111 31 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/hex.stat: -------------------------------------------------------------------------------- 1 | literals.hexDigits = Lower 2 | <<< lowercase 3 | 0x7F 4 | >>> 5 | 0x7f 6 | <<< uppercase 7 | literals.hexDigits = Upper 8 | === 9 | 0x7f 10 | >>> 11 | 0x7F 12 | <<< ignore suffix setting 13 | literals.long = Upper 14 | === 15 | 0xffffffffl 16 | >>> 17 | 0xffffffffL 18 | <<< also lowercase 0x 19 | 0Xfff 20 | >>> 21 | 0xfff 22 | <<< uppercase 0x if specified 23 | literals.hexPrefix = Upper 24 | === 25 | 0xfff 26 | >>> 27 | 0Xfff 28 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/literals/scientific.stat: -------------------------------------------------------------------------------- 1 | literals.scientific=Lower 2 | <<< lowercase double 3 | 1.0E7d 4 | >>> 5 | 1.0e7d 6 | <<< lowercase float 7 | 1.17549435E-38f 8 | >>> 9 | 1.17549435e-38f 10 | <<< uppercase double 11 | literals.scientific=Upper 12 | === 13 | 1.0e7d 14 | >>> 15 | 1.0E7d 16 | <<< uppercase float 17 | literals.scientific=Upper 18 | === 19 | 1.17549435e-38f 20 | >>> 21 | 1.17549435E-38f 22 | <<< keep double 23 | literals.scientific=Unchanged 24 | === 25 | 1.0e7d 26 | >>> 27 | 1.0e7d 28 | <<< keep float 29 | literals.scientific=Unchanged 30 | === 31 | 1.17549435E-38f 32 | >>> 33 | 1.17549435E-38f 34 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newdefault/ColumnWidth.stat: -------------------------------------------------------------------------------- 1 | preset = default 2 | <<< n-th column is OK, #975 3 | object Wat { 4 | val a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 5 | } 6 | >>> 7 | object Wat { 8 | val a = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 9 | } 10 | <<< native 82 11 | class Motion(val callsign: CallSign, val posOne: Vector3D, val posTwo: Vector3D) { 12 | def renderScene(scene: Scene, canvasContext: CanvasRenderingContext2D): Unit = { 13 | blah 14 | } 15 | } 16 | >>> 17 | class Motion( 18 | val callsign: CallSign, 19 | val posOne: Vector3D, 20 | val posTwo: Vector3D 21 | ) { 22 | def renderScene( 23 | scene: Scene, 24 | canvasContext: CanvasRenderingContext2D 25 | ): Unit = { 26 | blah 27 | } 28 | } 29 | <<< #1543 split on comma in assign shouldn't exceed maxColumn 30 | maxColumn = 30 31 | === 32 | object LongLines { 33 | LongLines( 34 | field1 = "123456789012345", 35 | field2 = "1234567890123451", 36 | field3 = """12345678901""", 37 | field4 = "12345678901234".! 38 | ) 39 | } 40 | >>> 41 | object LongLines { 42 | LongLines( 43 | field1 = 44 | "123456789012345", 45 | field2 = 46 | "1234567890123451", 47 | field3 = 48 | """12345678901""", 49 | field4 = 50 | "12345678901234".! 51 | ) 52 | } 53 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/AlwaysBeforeCurlyBraceLambdaParams.stat: -------------------------------------------------------------------------------- 1 | newlines.beforeCurlyLambdaParams = always 2 | <<< newline before lambda params 3 | lst.map { x => 4 | println(x) 5 | x + 1 6 | } 7 | >>> 8 | lst.map { 9 | x => 10 | println(x) 11 | x + 1 12 | } 13 | <<< apply to already formatted 14 | lst.map { x => 15 | x 16 | } 17 | >>> 18 | lst.map { 19 | x => 20 | x 21 | } 22 | <<< apply to one-liners as well 23 | lst.map { x => x } 24 | >>> 25 | lst.map { 26 | x => x 27 | } 28 | <<< but preserve newlines if inserted 29 | lst.map { 30 | x => 31 | x 32 | } 33 | >>> 34 | lst.map { 35 | x => 36 | x 37 | } 38 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/OffByOneParameterlessMethod.stat: -------------------------------------------------------------------------------- 1 | preset = defaultWithAlign 2 | newlines.sometimesBeforeColonInMethodReturnType = false 3 | maxColumn = 32 4 | danglingParentheses.preset = false 5 | <<< equals is at column + 1 6 | object Test { 7 | //-----------------------------| 8 | def test: Either[String, Int] = Right(0) 9 | } 10 | >>> 11 | object Test { 12 | //-----------------------------| 13 | def test: Either[ 14 | String, 15 | Int] = Right(0) 16 | } 17 | <<< left brace is at column + 1 18 | object Test { 19 | //-----------------------------| 20 | def ab: Either[String, Int] = { 21 | Right(0) 22 | } 23 | } 24 | >>> 25 | object Test { 26 | //-----------------------------| 27 | def ab: Either[ 28 | String, 29 | Int] = { 30 | Right(0) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/afterCurlyLambdaAlways.stat: -------------------------------------------------------------------------------- 1 | preset = default 2 | newlines.afterCurlyLambda = always 3 | 4 | <<< Preserve (when always) newline in lambda call 5 | def f = { 6 | something.call { x => 7 | 8 | g(x) 9 | } 10 | } 11 | >>> 12 | def f = { 13 | something.call { x => 14 | 15 | g(x) 16 | } 17 | } 18 | 19 | <<< Force empty line in lambda call with a newline 20 | def f = { 21 | something.call { x => 22 | g(x) 23 | } 24 | } 25 | >>> 26 | def f = { 27 | something.call { x => 28 | 29 | g(x) 30 | } 31 | } 32 | <<< Force empty line in lambda call without a newline 33 | def f = { 34 | something.call { x => g(x) 35 | } 36 | } 37 | >>> 38 | def f = { 39 | something.call { x => 40 | 41 | g(x) 42 | } 43 | } 44 | <<< Remove extra newlines in lambda call 45 | def f = { 46 | something.call { x => 47 | 48 | 49 | g(x) 50 | } 51 | } 52 | >>> 53 | def f = { 54 | something.call { x => 55 | 56 | g(x) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/afterCurlyLambdaSquash.stat: -------------------------------------------------------------------------------- 1 | newlines.afterCurlyLambda = squash 2 | 3 | <<< squash newline in lambda call 4 | def f = { 5 | something.call { x => 6 | 7 | g(x) 8 | } 9 | } 10 | >>> 11 | def f = { 12 | something.call { x => g(x) } 13 | } 14 | 15 | <<< squash no newline in lambda call 16 | def f = { 17 | something.call { x => g(x) 18 | } 19 | } 20 | >>> 21 | def f = { 22 | something.call { x => g(x) } 23 | } 24 | <<< squash no empty line in lambda call 25 | def f = { 26 | something.call { x => 27 | g(x) 28 | } 29 | } 30 | >>> 31 | def f = { 32 | something.call { x => g(x) } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/alwaysBeforeElseAfterCurlyIf.stat: -------------------------------------------------------------------------------- 1 | preset = default 2 | newlines.alwaysBeforeElseAfterCurlyIf = true 3 | 4 | <<< Insert line break between curly if and else 5 | if (someCond) { 6 | something() 7 | } else somethingElse() 8 | >>> 9 | if (someCond) { 10 | something() 11 | } 12 | else somethingElse() 13 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/alwaysBeforeMultilineDef.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 40 2 | newlines.alwaysBeforeMultilineDef = false 3 | 4 | <<< Wrap long line but don't add newline 5 | def foo = bar 6 | .flatMap(x => f(x)).map(x => g(x)) 7 | >>> 8 | def foo = bar 9 | .flatMap(x => f(x)) 10 | .map(x => g(x)) 11 | <<< Don't touch multiline function call 12 | def foo = Future({ 13 | val bar = fetchBar() 14 | bar.map(_ + 10) 15 | }) 16 | >>> 17 | def foo = Future({ 18 | val bar = fetchBar() 19 | bar.map(_ + 10) 20 | }) 21 | <<< Indent without comment 22 | def foo(a: Int): Int = 23 | ??? 24 | >>> 25 | def foo(a: Int): Int = 26 | ??? 27 | <<< Indent without comment with block 28 | def foo(a: Int): Int = 29 | { 30 | ??? } 31 | >>> 32 | def foo(a: Int): Int = { 33 | ??? 34 | } 35 | <<< Indent after comment 36 | def foo(a: Int): Int = // a comment 37 | ??? 38 | >>> 39 | def foo(a: Int): Int = // a comment 40 | ??? 41 | <<< Indent after comment with block 42 | def foo(a: Int): Int = // a comment 43 | { 44 | ??? } 45 | >>> 46 | def foo(a: Int): Int = // a comment 47 | { 48 | ??? 49 | } -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/newlines/newlineBetweenCurlyAndCatchFinally.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 80 2 | newlines.alwaysBeforeElseAfterCurlyIf = true 3 | <<< 1: try with curly, catch/finally without 4 | object Foo { 5 | try { 6 | a 7 | b 8 | } catch c finally d 9 | } 10 | >>> 11 | object Foo { 12 | try { 13 | a 14 | b 15 | } 16 | catch c 17 | finally d 18 | } 19 | <<< 2: try/catch with curly, finally without 20 | object Foo { 21 | try { a 22 | b} catch { case c => } finally d 23 | } 24 | >>> 25 | object Foo { 26 | try { 27 | a 28 | b 29 | } 30 | catch { case c => } 31 | finally d 32 | } 33 | <<< 3: try/catch/finally with curly 34 | object Foo { 35 | try { a 36 | b} catch { case c => } finally { d 37 | e} 38 | } 39 | >>> 40 | object Foo { 41 | try { 42 | a 43 | b 44 | } 45 | catch { case c => } 46 | finally { 47 | d 48 | e 49 | } 50 | } 51 | <<< 4: catch with curly, try/finally without 52 | object Foo { 53 | try a catch { case c => 54 | case d => } finally e 55 | } 56 | >>> 57 | object Foo { 58 | try a 59 | catch { 60 | case c => 61 | case d => 62 | } 63 | finally e 64 | } 65 | <<< 5: try with curly, finally without 66 | object Foo { 67 | try { a 68 | b} finally e 69 | } 70 | >>> 71 | object Foo { 72 | try { 73 | a 74 | b 75 | } 76 | finally e 77 | } 78 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/optIn/AnnotationParam.stat: -------------------------------------------------------------------------------- 1 | optIn.annotationNewlines = true 2 | <<< class 3 | case class Foo( 4 | @hidden 5 | foo: String = "bar", 6 | @hidden x: Int 7 | ) 8 | >>> 9 | case class Foo( 10 | @hidden 11 | foo: String = "bar", 12 | @hidden x: Int 13 | ) 14 | <<< class 2 15 | case class Foo( @hidden 16 | foo: String = "bar", @hidden x: Int ) 17 | >>> 18 | case class Foo( 19 | @hidden 20 | foo: String = "bar", 21 | @hidden x: Int 22 | ) 23 | <<< def 2 24 | def foo( @hidden 25 | foo: String = "bar", @hidden x: Int ): Int = 2 26 | >>> 27 | def foo( 28 | @hidden 29 | foo: String = "bar", 30 | @hidden x: Int 31 | ): Int = 2 32 | <<< caveat: spaces are preserved even for large annotations 33 | @annot("aaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "cccccccccccccccc") def foo() = 2 34 | >>> 35 | @annot( 36 | "aaaaaaaaaaaaaaaaaaaaaaaaaa", 37 | "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 38 | "cccccccccccccccc" 39 | ) def foo() = 2 40 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/optIn/BreakChainOnFirstMethodDot.stat: -------------------------------------------------------------------------------- 1 | optIn.breakChainOnFirstMethodDot = true 2 | <<< keep the new line on method call if it's already there 3 | execute(request) 4 | .map(success => Xor.Right(success)) 5 | >>> 6 | execute(request) 7 | .map(success => Xor.Right(success)) 8 | <<< don't add new line on method call 9 | execute(request).map(success => Xor.Right(success)) 10 | >>> 11 | execute(request).map(success => Xor.Right(success)) 12 | <<< keep the alignment for chain line breaks 13 | execute(request) 14 | .map(success => Xor.Right(success)) 15 | .map(identity) 16 | >>> 17 | execute(request) 18 | .map(success => Xor.Right(success)) 19 | .map(identity) 20 | <<< don't add new line on chained method calls 21 | execute(request).map(success => Xor.Right(success)).map(identity) 22 | >>> 23 | execute(request).map(success => Xor.Right(success)).map(identity) 24 | <<< reduce multiple new lines on method call to one 25 | execute(request) 26 | 27 | .map(success => Xor.Right(success)) 28 | >>> 29 | execute(request) 30 | .map(success => Xor.Right(success)) 31 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/optIn/SelectChain.stat: -------------------------------------------------------------------------------- 1 | includeCurlyBraceInSelectChains = true 2 | <<< include curly 3 | def acceptParticipants = 4 | actions[Lottery] 5 | .handleCommand { 6 | cmd: AddParticipant => ParticipantAdded(cmd.name, id) 7 | } 8 | .handleEvent { 9 | evt: ParticipantAdded => this.addParticipant(evt.name) 10 | } 11 | >>> 12 | def acceptParticipants = 13 | actions[Lottery] 14 | .handleCommand { cmd: AddParticipant => 15 | ParticipantAdded(cmd.name, id) 16 | } 17 | .handleEvent { evt: ParticipantAdded => 18 | this.addParticipant(evt.name) 19 | } 20 | <<< .value #639 21 | val x = Def.taskDyn { 22 | println(1) 23 | }.value 24 | >>> 25 | val x = Def.taskDyn { 26 | println(1) 27 | }.value 28 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/optIn/SelfAnnotation.stat: -------------------------------------------------------------------------------- 1 | optIn.selfAnnotationNewline = true 2 | maxColumn = 20 3 | <<< #938 4 | trait a { self => 5 | blah 6 | } 7 | >>> 8 | trait a { self => 9 | blah 10 | } 11 | <<< #938 2 12 | trait a { 13 | self => 14 | blah 15 | } 16 | >>> 17 | trait a { 18 | self => 19 | blah 20 | } 21 | <<< #938 maxColumn is still respected 22 | trait a { selfaaaaaaaaaaaaaaaa => 23 | blah 24 | } 25 | >>> 26 | trait a { 27 | selfaaaaaaaaaaaaaaaa => 28 | blah 29 | } 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/optIn/forceBlankLineBeforeDocstring.stat: -------------------------------------------------------------------------------- 1 | preset = default 2 | <<< docstring does not force line break 3 | docstrings.forceBlankLineBefore = false 4 | === 5 | object Stuff { 6 | /** Some function */ 7 | def hello = () 8 | } 9 | >>> 10 | object Stuff { 11 | /** Some function */ 12 | def hello = () 13 | } 14 | <<< force blank line 15 | docstrings.forceBlankLineBefore = true 16 | === 17 | object Stuff { 18 | /** Some function */ 19 | def hello = () 20 | } 21 | >>> 22 | object Stuff { 23 | 24 | /** Some function */ 25 | def hello = () 26 | } 27 | <<< support deprecated name with false 28 | optIn.forceBlankLineBeforeDocstring = false 29 | === 30 | object Stuff { 31 | /** Some function */ 32 | def hello = () 33 | } 34 | >>> 35 | object Stuff { 36 | /** Some function */ 37 | def hello = () 38 | } 39 | <<< support deprecated name with true 40 | optIn.forceBlankLineBeforeDocstring = true 41 | === 42 | object Stuff { 43 | /** Some function */ 44 | def hello = () 45 | } 46 | >>> 47 | object Stuff { 48 | 49 | /** Some function */ 50 | def hello = () 51 | } 52 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/AsciiSortImports.stat: -------------------------------------------------------------------------------- 1 | rewrite.rules = [AsciiSortImports] 2 | 3 | <<< ascii sorting 4 | import a.{ 5 | ~>, 6 | lowercase, 7 | Uppercase, 8 | `symbol` 9 | } 10 | >>> 11 | import a.{Uppercase, `symbol`, lowercase, ~>} 12 | <<< ascii sorting (format:off) 13 | // format: off 14 | import a.{ 15 | ~>, 16 | lowercase, 17 | Uppercase, 18 | `symbol` 19 | } 20 | 21 | >>> 22 | // format: off 23 | import a.{ 24 | ~>, 25 | lowercase, 26 | Uppercase, 27 | `symbol` 28 | } 29 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/AvoidInfix2.stat: -------------------------------------------------------------------------------- 1 | rewrite.rules = [AvoidInfix] 2 | rewrite.neverInfix.includeFilters = [".*"] 3 | <<< right assoc 4 | lst :: foo 5 | >>> 6 | lst :: foo 7 | <<< basic 8 | lst :+ foo 9 | >>> 10 | lst.:+(foo) 11 | <<< basic (format:off) 12 | // format: off 13 | lst :+ foo 14 | 15 | >>> 16 | // format: off 17 | lst :+ foo 18 | <<< default scalatest 19 | runner.parser = source 20 | === 21 | behavior of "..." { 22 | a shouldBe b 23 | } 24 | behaviour of "..." { 25 | a shouldBe b 26 | } 27 | behavi.or of "..." { 28 | a shouldBe b 29 | } 30 | >>> 31 | behavior of "..." { 32 | a shouldBe b 33 | } 34 | behaviour.of("..." { 35 | a shouldBe b 36 | }) 37 | behavi.or.of("..." { 38 | a shouldBe b 39 | }) 40 | <<< #3699 1 41 | rewrite.neverInfix.excludeFilters = [ "shouldBe" ] 42 | === 43 | behavior of "..." { 44 | a shouldBe b 45 | } 46 | >>> 47 | behavior.of("..." { 48 | a shouldBe b 49 | }) 50 | <<< #3699 2 51 | rewrite.neverInfix.excludeFilters = [ "of" ] 52 | === 53 | behavior of "..." { 54 | a shouldBe b 55 | } 56 | >>> 57 | behavior of "..." { 58 | a.shouldBe(b) 59 | } 60 | <<< #3699 3 61 | runner.parser = source 62 | rewrite.neverInfix.excludeFilters = [ "behaviour\\.of" ] 63 | === 64 | behavior of "..." { 65 | a shouldBe b 66 | } 67 | behaviour of "..." { 68 | a shouldBe b 69 | } 70 | >>> 71 | behavior.of("..." { 72 | a.shouldBe(b) 73 | }) 74 | behaviour of "..." { 75 | a.shouldBe(b) 76 | } 77 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/RedundantBraces-precedence.stat: -------------------------------------------------------------------------------- 1 | rewrite.rules = [RedundantBraces] 2 | rewrite.redundantBraces.generalExpressions = true 3 | <<< infix operator precedence 4 | {1 + 2} * 3 5 | >>> 6 | { 1 + 2 } * 3 7 | <<< infix operator precedence negative 8 | 1 + { 2 * 3 } 9 | >>> 10 | 1 + 2 * 3 11 | <<< infix operator associativity 12 | {a :: b} :: c 13 | >>> 14 | { a :: b } :: c 15 | <<< infix operator associativity negative 16 | a :: {b :: c} 17 | >>> 18 | a :: b :: c 19 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/RedundantBraces748.stat: -------------------------------------------------------------------------------- 1 | rewrite.rules = [ 2 | RedundantBraces 3 | ] 4 | <<< #748 5 | object a { 6 | def init() = { 7 | val task = new TimerTask { 8 | override def run(): Unit = println("Test") 9 | } 10 | } 11 | } 12 | 13 | 14 | >>> 15 | object a { 16 | def init() = { 17 | val task = new TimerTask { 18 | override def run(): Unit = println("Test") 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/SortImports.stat: -------------------------------------------------------------------------------- 1 | rewrite.rules = [SortImports] 2 | <<< basic 3 | import a.b.{ 4 | c, 5 | a, 6 | b 7 | }, k.{ 8 | g, f 9 | } 10 | >>> 11 | import a.b.{a, b, c}, k.{f, g} 12 | <<< nested 13 | object a { 14 | import a.b.{ 15 | c, 16 | b 17 | } 18 | } 19 | >>> 20 | object a { 21 | import a.b.{b, c} 22 | } 23 | <<< nested (format:off) 24 | object a { 25 | // format: off 26 | import a.b.{ 27 | c, 28 | b 29 | } 30 | } 31 | 32 | >>> 33 | object a { 34 | // format: off 35 | import a.b.{ 36 | c, 37 | b 38 | } 39 | } 40 | <<< nested (format:off partial) 41 | object a { 42 | import a.b.{ 43 | c, 44 | // format is not off 45 | b 46 | } 47 | import a.b.{ 48 | c, 49 | // format: off 50 | b 51 | } 52 | } 53 | 54 | >>> 55 | object a { 56 | import a.b.{ 57 | // format is not off 58 | b, 59 | c 60 | } 61 | import a.b.{ 62 | c, 63 | // format: off 64 | b 65 | } 66 | } 67 | <<< sorting 68 | import a.{ 69 | ~>, 70 | lowercase, 71 | Uppercase, 72 | `symbol` 73 | } 74 | >>> 75 | import a.{`symbol`, ~>, lowercase, Uppercase} 76 | <<< caveat: rename/wildcard/unimport 77 | import a.{ 78 | zzzz => _, 79 | bar 80 | } 81 | >>> 82 | import a.{bar, zzzz => _} 83 | <<< caveat: comments 84 | import a.{ 85 | c, // comment for c 86 | b 87 | } 88 | >>> 89 | import a.{ 90 | b, 91 | c // comment for c 92 | } 93 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/rewrite/SortModifiers_Mod_With_No_Token.source: -------------------------------------------------------------------------------- 1 | maxColumn = 200 #to not disturb the output too much 2 | rewrite { 3 | rules = [SortModifiers] 4 | sortModifiers { 5 | order = ["private", "protected" , "abstract", "final", "sealed", "implicit", "override", "lazy"] 6 | } 7 | } 8 | 9 | 10 | <<< Almost bug in convoluted modifiers 11 | package test 12 | 13 | sealed private[test] trait Test { 14 | def name: String 15 | } 16 | 17 | final private[test] object Tests { 18 | 19 | final protected[Tests] case object Test1 extends Test { 20 | override final lazy implicit val name: String = "foo" 21 | } 22 | 23 | final case class Test2(override implicit val name: String) extends Test 24 | 25 | private[test] final class Test3(override val name: String = "42", final private[this] implicit val foo: Int) extends Test 26 | } 27 | >>> 28 | package test 29 | 30 | private[test] sealed trait Test { 31 | def name: String 32 | } 33 | 34 | private[test] final object Tests { 35 | 36 | protected[Tests] final case object Test1 extends Test { 37 | final implicit override lazy val name: String = "foo" 38 | } 39 | 40 | final case class Test2(implicit override val name: String) extends Test 41 | 42 | private[test] final class Test3(override val name: String = "42", private[this] final implicit val foo: Int) extends Test 43 | } 44 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/Dialect.stat: -------------------------------------------------------------------------------- 1 | <<< extractor 2 | val List(a : _ *) = 2 3 | >>> 4 | val List(a: _*) = 2 5 | <<< trait parameters 6 | trait T(a : Int) 7 | >>> 8 | trait T(a: Int) 9 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/ExportGivens.stat: -------------------------------------------------------------------------------- 1 | <<< wildcard import 2 | object B { 3 | export A._ 4 | export A.given} 5 | >>> 6 | object B { 7 | export A._ 8 | export A.given 9 | } 10 | <<< merged export clauses 11 | object B { 12 | export A.{given, _} 13 | } 14 | >>> 15 | object B { 16 | export A.{given, _} 17 | } 18 | <<< export given of type 19 | maxColumn = 20 20 | === 21 | export A.{given T1, given T2, given T3} 22 | >>> 23 | export A.{ 24 | given T1, 25 | given T2, 26 | given T3 27 | } 28 | <<< export given of type doesn't break 29 | maxColumn = 10 30 | === 31 | export A.{given T1, given T2, given T3} 32 | >>> 33 | export A.{ 34 | given T1, 35 | given T2, 36 | given T3 37 | } 38 | <<< with wildcard argument 39 | maxColumn = 25 40 | indent.main = 4 41 | === 42 | export Instances.{given Ordering[?], given ExecutionContext} 43 | >>> 44 | export Instances.{ 45 | given Ordering[?], 46 | given ExecutionContext 47 | } 48 | <<< by-type mixed with by-name 49 | maxColumn = 25 50 | indent.main = 4 51 | === 52 | export Instances.{im, given Ordering[?]} 53 | >>> 54 | export Instances.{ 55 | im, 56 | given Ordering[?] 57 | } 58 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/GivenPatterns.stat: -------------------------------------------------------------------------------- 1 | <<< for comprehension 2 | for given Context <- applicationContexts yield () 3 | >>> 4 | for given Context <- applicationContexts yield () 5 | <<< for comprehension with parens 6 | for (given Context <- applicationContexts) 7 | yield () 8 | >>> 9 | for (given Context <- applicationContexts) 10 | yield () 11 | <<< match case 12 | context match { 13 | case (ctx @ given Context) => ctx 14 | } 15 | >>> 16 | context match { 17 | case (ctx @ given Context) => ctx 18 | } 19 | <<< match case tuple 20 | pair match { 21 | case (ctx @ given Context, y) => ctx 22 | } 23 | >>> 24 | pair match { 25 | case (ctx @ given Context, y) => ctx 26 | } 27 | <<< don't break before nor after given 28 | maxColumn = 10 29 | === 30 | context match { 31 | case (ctx @ given Context) => ctx 32 | case (ctx @ given Context) => ctx 33 | case (ctx @ given Context) => ctx 34 | } 35 | >>> 36 | context match { 37 | case (ctx @ given Context) => 38 | ctx 39 | case (ctx @ given Context) => 40 | ctx 41 | case (ctx @ given Context) => 42 | ctx 43 | } 44 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/ImportingGivens.stat: -------------------------------------------------------------------------------- 1 | <<< wildcard import 2 | object B { 3 | import A._ 4 | import A.given} 5 | >>> 6 | object B { 7 | import A._ 8 | import A.given 9 | } 10 | <<< merged import clauses 11 | object B { 12 | import A.{given, _} 13 | } 14 | >>> 15 | object B { 16 | import A.{given, _} 17 | } 18 | <<< import given of type 19 | maxColumn = 20 20 | === 21 | import A.{given T1, given T2, given T3} 22 | >>> 23 | import A.{ 24 | given T1, 25 | given T2, 26 | given T3 27 | } 28 | <<< import given of type doesn't break 29 | maxColumn = 10 30 | === 31 | import A.{given T1, given T2, given T3} 32 | >>> 33 | import A.{ 34 | given T1, 35 | given T2, 36 | given T3 37 | } 38 | <<< with wildcard argument 39 | maxColumn = 25 40 | indent.main = 4 41 | === 42 | import Instances.{given Ordering[?], given ExecutionContext} 43 | >>> 44 | import Instances.{ 45 | given Ordering[?], 46 | given ExecutionContext 47 | } 48 | <<< by-type mixed with by-name 49 | maxColumn = 25 50 | indent.main = 4 51 | === 52 | import Instances.{im, given Ordering[?]} 53 | >>> 54 | import Instances.{ 55 | im, 56 | given Ordering[?] 57 | } 58 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/Infix.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< simple infix 3 | infix def a(param: Int)=param 4 | >>> 5 | infix def a(param: Int) = param 6 | <<< soft identifier infix 7 | infix def infix(infix: Int)=infix 8 | >>> 9 | infix def infix(infix: Int) = infix 10 | <<< infix long break 11 | maxColumn = 20 12 | === 13 | override protected transparent inline infix def choose(b: Boolean): A = {if(b) {new A} else {new B}} 14 | >>> 15 | override protected transparent inline infix def choose( 16 | b: Boolean 17 | ): A = { 18 | if (b) { new A } 19 | else { new B } 20 | } 21 | <<< infix type 22 | infix type or [X , Y] 23 | >>> 24 | infix type or[X, Y] 25 | <<< infix class 26 | infix class A[B, C] 27 | >>> 28 | infix class A[B, C] 29 | <<< infix trait 30 | infix trait A[B, C] 31 | >>> 32 | infix trait A[B, C] 33 | <<< infix extension method 34 | maxColumn = 30 35 | === 36 | extension (i: Int) infix def zero(other: Int): Int = 0 37 | >>> 38 | extension (i: Int) 39 | infix def zero( 40 | other: Int 41 | ): Int = 0 42 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/OpaqueType.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< simple opaque type 3 | opaque type F = X 4 | >>> 5 | opaque type F = X 6 | <<< long opaque type 7 | maxColumn = 20 8 | === 9 | opaque type HelloIAmAnOpaqueTypeTerry = NiceToMeetYouTerry 10 | >>> 11 | opaque type HelloIAmAnOpaqueTypeTerry = 12 | NiceToMeetYouTerry 13 | <<< opaque type bounds 14 | maxColumn = 15 15 | newlines.beforeTypeBounds = fold 16 | === 17 | opaque type VeryLongClassName <: AType = AB 18 | >>> 19 | opaque type VeryLongClassName 20 | <: AType = AB 21 | <<< mixed modifiers 22 | private opaque type T = List[Int] 23 | >>> 24 | private opaque type T = List[Int] 25 | <<< rewrite modifiers default 26 | rewrite.rules = [SortModifiers] 27 | === 28 | opaque private type T = List[Int] 29 | >>> 30 | private opaque type T = List[Int] 31 | <<< rewrite modifiers 32 | rewrite.rules = [SortModifiers] 33 | rewrite.sortModifiers { 34 | order = ["opaque", "private"] 35 | } 36 | === 37 | opaque private type T = List[Int] 38 | >>> 39 | opaque private type T = List[Int] 40 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/Open.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< class 3 | open class Foobar() 4 | >>> 5 | open class Foobar() 6 | <<< object 7 | open object Foobar 8 | >>> 9 | open object Foobar 10 | <<< trait 11 | open trait Foobar 12 | >>> 13 | open trait Foobar 14 | <<< implicit open 15 | implicit open class Foobar() 16 | >>> 17 | implicit open class Foobar() 18 | <<< open implicit 19 | open implicit class Foobar() 20 | >>> 21 | open implicit class Foobar() 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/StarImport.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< simple wildcard import 3 | import a . b . c . * 4 | >>> 5 | import a.b.c.* 6 | <<< star named import 7 | import a . b . c . `*` 8 | >>> 9 | import a.b.c.`*` 10 | <<< simple wildcard export 11 | export a . b . c . * 12 | >>> 13 | export a.b.c.* 14 | <<< star named export 15 | export a . b . c . `*` 16 | >>> 17 | export a.b.c.`*` 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/Type.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< type inside block 3 | maxColumn = 30 4 | === 5 | def hello() = { 6 | type T 7 | val a : T 8 | } 9 | >>> 10 | def hello() = { 11 | type T 12 | val a: T 13 | } 14 | <<< type inside block long 15 | maxColumn = 20 16 | === 17 | def hello() = { 18 | type T[ AAAAAAA <: BBBBBB [?] ] 19 | val a : T 20 | } 21 | >>> 22 | def hello() = { 23 | type T[AAAAAAA <: BBBBBB[ 24 | ? 25 | ]] 26 | val a: T 27 | } 28 | 29 | <<< type inside block longer 30 | maxColumn = 20 31 | === 32 | def hello() = { 33 | type T[ AAAAAAAAAAAAA <: BBBBBBBBBBBBBB [? <: B] ] 34 | val a : T 35 | } 36 | >>> 37 | def hello() = { 38 | type T[ 39 | AAAAAAAAAAAAA <: BBBBBBBBBBBBBB[ 40 | ? <: B 41 | ] 42 | ] 43 | val a: T 44 | } 45 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scala3/Vararg.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< simple invocation 3 | val a = method(0, 1,"", others*) 4 | >>> 5 | val a = method(0, 1, "", others*) 6 | <<< old apply 7 | val a = method(0, 1,"", others: _*) 8 | >>> 9 | val a = method(0, 1, "", others: _*) 10 | <<< pattern match 11 | a match {case List(xs*) => 1 12 | case Nil => 2} 13 | >>> 14 | a match { 15 | case List(xs*) => 1 16 | case Nil => 2 17 | } 18 | <<< normal usage 19 | val a = List(0, 1, 1*2) 20 | >>> 21 | val a = List(0, 1, 1 * 2) 22 | <<< #4133 intellij-scala tasty-reader TreePrinter.scala 23 | rewrite.scala3.convertToNewSyntax = true 24 | === 25 | node match { 26 | case Node3(PACKAGE, _, Seq(Node3(TERMREFpkg, Seq("scala.annotation.internal"), zxc), children: _*)) => 27 | children.filterNot(_.tag == IMPORT).exists { 28 | case Node3(TYPEDEF, Seq("SourceFile"), _) => true 29 | case _ => false 30 | } 31 | case _ => 32 | false 33 | } 34 | >>> 35 | node match { 36 | case Node3( 37 | PACKAGE, 38 | _, 39 | Seq(Node3(TERMREFpkg, Seq("scala.annotation.internal"), zxc), children*) 40 | ) => 41 | children.filterNot(_.tag == IMPORT).exists { 42 | case Node3(TYPEDEF, Seq("SourceFile"), _) => true 43 | case _ => false 44 | } 45 | case _ => 46 | false 47 | } 48 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scalajs/If.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< while condition is like if 3 | while (!hasReachedEof(curr) && 4 | !statementStarts.contains(hash(tokens(curr.splits.length).left))) { 5 | foo 6 | } 7 | >>> 8 | while ( 9 | !hasReachedEof(curr) && 10 | !statementStarts.contains(hash(tokens(curr.splits.length).left)) 11 | ) { 12 | foo 13 | } 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scalajs/Import.source: -------------------------------------------------------------------------------- 1 | 2 | <<< break #101 3 | import org.scalajs.dom.experimental.serviceworkers.{ServiceWorkerGlobalScope, ServiceWorkerRegistration} 4 | >>> 5 | import org.scalajs.dom.experimental.serviceworkers.{ 6 | ServiceWorkerGlobalScope, ServiceWorkerRegistration 7 | } 8 | <<< break #101 short 2 9 | import org.{Aaaa, Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Ccccccccccccccccccccccccccccccc, D, E, F, G, H, I, J, K, L} 10 | >>> 11 | import org.{ 12 | Aaaa, Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Ccccccccccccccccccccccccccccccc, D, E, 13 | F, G, H, I, J, K, L 14 | } 15 | 16 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scalajs/TermApply.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< breaking cost #158 3 | object ReferrerPolicy { 4 | val `no-referrer-when-downgrade` = "no-referrer-when-downgrade".asInstanceOf[ 5 | ReferrerPolicy] 6 | val `origin-when-cross-origin` = "origin-when-cross-origin".asInstanceOf[ 7 | ReferrerPolicy] 8 | } 9 | >>> 10 | object ReferrerPolicy { 11 | val `no-referrer-when-downgrade` = 12 | "no-referrer-when-downgrade".asInstanceOf[ReferrerPolicy] 13 | val `origin-when-cross-origin` = 14 | "origin-when-cross-origin".asInstanceOf[ReferrerPolicy] 15 | } 16 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/scalajs/Type.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< type refinement 3 | type ScalaJSPlugin = NscPlugin { 4 | def registerModuleExports(sym: ScalaJSJUnitPluginComponent.global.Symbol): Unit 5 | } 6 | >>> 7 | type ScalaJSPlugin = NscPlugin { 8 | def registerModuleExports( 9 | sym: ScalaJSJUnitPluginComponent.global.Symbol): Unit 10 | } 11 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/AfterKeywordBeforeParen.stat: -------------------------------------------------------------------------------- 1 | spaces.afterKeywordBeforeParen = false 2 | <<< reformats if 3 | if (a) println("HELLO!") 4 | >>> 5 | if(a) println("HELLO!") 6 | <<< reformats while 7 | while (a) println("HELLO!") 8 | >>> 9 | while(a) println("HELLO!") 10 | <<< reformats for 11 | for (a <- as) println("HELLO!") 12 | >>> 13 | for(a <- as) println("HELLO!") 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/AfterSymbolicDefs.stat: -------------------------------------------------------------------------------- 1 | spaces.afterSymbolicDefs = true 2 | <<< #915 Space on both sides of operator method definition (positive) 3 | trait Test[A] { 4 | def <=>[B](that: Test[B]): Int 5 | } 6 | >>> 7 | trait Test[A] { 8 | def <=> [B](that: Test[B]): Int 9 | } 10 | <<< #915 Space on both sides of operator method definition (negative) 11 | trait Test[A] { 12 | def A_~>[B](that: Test[B]): Int 13 | } 14 | >>> 15 | trait Test[A] { 16 | def A_~>[B](that: Test[B]): Int 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/BeforeContextBoundColonIfMultipleBounds.stat: -------------------------------------------------------------------------------- 1 | spaces.beforeContextBoundColon = ifMultipleBounds 2 | <<< space before colon #180 3 | def map[T: Class](f: N => T): S[T] 4 | >>> 5 | def map[T: Class](f: N => T): S[T] 6 | <<< space before colon 2 #180 7 | def orderLaws[A:Eq:Arbitrary] = O 8 | >>> 9 | def orderLaws[A : Eq : Arbitrary] = O 10 | <<< non-ident before colon 11 | def myMethod[F[_]:Functor](): Foo 12 | >>> 13 | def myMethod[F[_]: Functor](): Foo 14 | <<< space before colon with subtype bound #1391 15 | final class Test[A <: B: ClassTag] 16 | >>> 17 | final class Test[A <: B : ClassTag] 18 | <<< single or multiple context bounds, ifMultipleBounds 19 | runner.parser = source 20 | spaces.beforeContextBoundColon = ifMultipleBounds 21 | === 22 | final class Test[B: ClassTag] 23 | final class Test[A <: B: ClassTag] 24 | final class Test[A <: B: ClassTag: Seq] 25 | >>> 26 | final class Test[B: ClassTag] 27 | final class Test[A <: B : ClassTag] 28 | final class Test[A <: B : ClassTag : Seq] 29 | <<< single or multiple context bounds, ifMultipleContextBounds 30 | runner.parser = source 31 | spaces.beforeContextBoundColon = ifMultipleContextBounds 32 | === 33 | final class Test[B: ClassTag] 34 | final class Test[A <: B: ClassTag] 35 | final class Test[A <: B: ClassTag: Seq] 36 | >>> 37 | final class Test[B: ClassTag] 38 | final class Test[A <: B: ClassTag] 39 | final class Test[A <: B : ClassTag : Seq] 40 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/BeforeContextBoundColonTrue.stat: -------------------------------------------------------------------------------- 1 | spaces.beforeContextBoundColon = true 2 | <<< space before colon #180 3 | def map[T: Class](f: N => T): S[T] 4 | >>> 5 | def map[T : Class](f: N => T): S[T] 6 | <<< space before colon 2 #180 7 | def orderLaws[A:Eq:Arbitrary] = O 8 | >>> 9 | def orderLaws[A : Eq : Arbitrary] = O 10 | <<< non-ident before colon 11 | def myMethod[F[_]:Functor](): Foo 12 | >>> 13 | def myMethod[F[_] : Functor](): Foo 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/Constructor.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 100 2 | <<< Space between annotation and ctor argument list 3 | class A @Inject()(b: C) 4 | >>> 5 | class A @Inject() (b: C) 6 | 7 | <<< Space between annotation and ctor argument list (with multiple argument list) 8 | class MyComponent @Inject()(ctx: Context)(ws: WSClient) 9 | >>> 10 | class MyComponent @Inject() (ctx: Context)(ws: WSClient) 11 | 12 | <<< Do not add add a space when a constructor has multiple argument lists #1528 13 | new ShardEntity(rts) (onMessage) 14 | >>> 15 | new ShardEntity(rts)(onMessage) 16 | <<< preserve ctor lambda with zero args 17 | val foo = new Bar { () => 18 | println("a") 19 | } 20 | >>> 21 | val foo = new Bar { () => 22 | println("a") 23 | } 24 | <<< preserve ctor lambda with wildcard arg 25 | val foo = new Bar { _ => 26 | println("a") 27 | } 28 | >>> 29 | val foo = new Bar { _ => 30 | println("a") 31 | } 32 | <<< preserve ctor one line lambda with zero args 33 | val foo = new Bar { () => println("a") } 34 | >>> 35 | val foo = new Bar { () => println("a") } 36 | <<< preserve ctor lambda with zero args and parens 37 | val foo = new Bar ( () => println("a") ) 38 | >>> 39 | val foo = new Bar(() => println("a")) 40 | <<< squash ctor lambda with zero args and parens 41 | val foo = new Bar(() => 42 | println("a") 43 | ) 44 | >>> 45 | val foo = new Bar(() => println("a")) 46 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/Hacking.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 40 2 | <<< Spaces in parentheses 3 | spaces.inParentheses = true 4 | === 5 | function(a, b, c) 6 | >>> 7 | function( a, b, c ) 8 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/ImportCurlyBraces.source: -------------------------------------------------------------------------------- 1 | spaces.inImportCurlyBraces = true 2 | <<< #424 3 | import play.api.libs.json.{JsObject, JsString, Json} 4 | 5 | object Hase { 6 | 7 | def name(xs: OtherObject): String = { 8 | s"Hallo ${xs.name}" 9 | } 10 | 11 | } 12 | >>> 13 | import play.api.libs.json.{ JsObject, JsString, Json } 14 | 15 | object Hase { 16 | 17 | def name(xs: OtherObject): String = { 18 | s"Hallo ${xs.name}" 19 | } 20 | 21 | } 22 | <<< import 23 | import a.b.{c => d} 24 | >>> 25 | import a.b.{ c => d } 26 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/InByNameTypes.stat: -------------------------------------------------------------------------------- 1 | spaces.inByNameTypes = false 2 | <<< No space in by-name parameter 3 | def foo(a: => A) = ??? 4 | >>> 5 | def foo(a: =>A) = ??? 6 | <<< Space in function parameter 7 | def foo(a: B => A) = ??? 8 | >>> 9 | def foo(a: B => A) = ??? 10 | <<< More complex by-name parameter 11 | def foo(a: => Option[Set[A]] :: HNill) = ??? 12 | >>> 13 | def foo(a: =>Option[Set[A]] :: HNill) = ??? 14 | <<< More complex function parameter 15 | def foo(a: List[B] => Option[Set[A]] :: HNill) = ??? 16 | >>> 17 | def foo(a: List[B] => Option[Set[A]] :: HNill) = ??? 18 | <<< One space between parameter name and by-name type 19 | def foo(a: =>A) = ??? 20 | >>> 21 | def foo(a: =>A) = ??? 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/InParentheses.stat: -------------------------------------------------------------------------------- 1 | spaces.inParentheses = true 2 | maxColumn = 40 3 | danglingParentheses.preset = false 4 | <<< Spaces in parentheses 5 | function(a, b, c) 6 | >>> 7 | function( a, b, c ) 8 | <<< no arg 9 | function() 10 | >>> 11 | function() 12 | <<< def 13 | def x(foo: Int) = 2 14 | >>> 15 | def x( foo: Int ) = 2 16 | <<< tuple 17 | def x = (1, 2) 18 | >>> 19 | def x = ( 1, 2 ) 20 | <<< maxColumn 21 | def x = (1, 2, aaaaaaaaaaaaaawwwwsssssssssswa) 22 | >>> 23 | def x = ( 24 | 1, 25 | 2, 26 | aaaaaaaaaaaaaawwwwsssssssssswa ) 27 | <<< maxColumn apply 28 | def foo = bar(aaaaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccc) 29 | >>> 30 | def foo = bar( 31 | aaaaaaaaaaaaa, 32 | bbbbbbbbbbbbbb, 33 | cccccccccc ) 34 | <<< maxColumn apply 2 35 | def foo = bar(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccc) 36 | >>> 37 | def foo = bar( 38 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 39 | bbbbbbbbbbbbbb, 40 | cccccccccc ) 41 | <<< brackets 42 | function[A](a, b, c) 43 | >>> 44 | function[A]( a, b, c ) 45 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/InterpolatedStringCurlyBraces.stat: -------------------------------------------------------------------------------- 1 | spaces.inInterpolatedStringCurlyBraces = false 2 | 3 | <<< No spaces for simple variables 4 | s"Hello ${ the } world!" 5 | >>> 6 | s"Hello ${the} world!" 7 | 8 | <<< No spaces for complex statements 9 | s"Hello ${ th.e } ${ functional() } world!" 10 | >>> 11 | s"Hello ${th.e} ${functional()} world!" 12 | 13 | <<< No spaces for multiline statements 14 | s"""Hello ${ 15 | the 16 | } ${ 17 | functional() 18 | }world!""" 19 | >>> 20 | s"""Hello ${the} ${functional()}world!""" 21 | 22 | <<< Always have spaces for simple variables 23 | spaces.inInterpolatedStringCurlyBraces = true 24 | === 25 | s"Hello ${the} world!" 26 | >>> 27 | s"Hello ${ the } world!" 28 | 29 | <<< Always have spaces for complex statements 30 | spaces.inInterpolatedStringCurlyBraces = true 31 | === 32 | s"Hello ${th.e} ${functional()} world!" 33 | >>> 34 | s"Hello ${ th.e } ${ functional() } world!" 35 | 36 | <<< Always have spaces for multiline statements 37 | spaces.inInterpolatedStringCurlyBraces = true 38 | === 39 | s"""Hello ${ 40 | the 41 | } ${ 42 | functional() 43 | }world!""" 44 | >>> 45 | s"""Hello ${ the } ${ functional() }world!""" 46 | 47 | <<< Shouldn't add spaces to imports 48 | spaces.inInterpolatedStringCurlyBraces = true 49 | === 50 | import play.api.libs.json.{JsObject, JsString, Json} 51 | >>> 52 | import play.api.libs.json.{JsObject, JsString, Json} 53 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/NeverAroundInfixTypes.stat: -------------------------------------------------------------------------------- 1 | spaces.neverAroundInfixTypes = ["##"] 2 | maxColumn = 40 3 | <<< never around infix types 4 | val hlistForFoo: Generic[Foo] ## Repr = 1 :: "xxx" :: HNil 5 | >>> 6 | val hlistForFoo: Generic[Foo]##Repr = 7 | 1 :: "xxx" :: HNil 8 | <<< never around infix types (not an infix term) 9 | val x: F[X] ## B = f##b 10 | >>> 11 | val x: F[X]##B = f ## b 12 | <<< use aroundSymbolicInfixOperators 13 | maxColumn = 80 14 | spaces.neverAroundInfixTypes = [] 15 | spaces.aroundSymbolicInfixOperators.exclude = [ "^##$", "==" ] 16 | === 17 | object a { 18 | def f: Foo ## Repr 19 | def g(a: Column, b: Column): Boolean = a === b || a###b 20 | def e(a: Int, b: Int) = a ## b || a == b || a!=b 21 | } 22 | >>> 23 | object a { 24 | def f: Foo##Repr 25 | def g(a: Column, b: Column): Boolean = a===b || a ### b 26 | def e(a: Int, b: Int) = a##b || a==b || a != b 27 | } 28 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/spaces/Scalatest.stat: -------------------------------------------------------------------------------- 1 | spaces.afterTripleEquals = true 2 | <<< Space before triple equals 3 | foo must ===(123) 4 | >>> 5 | foo must === (123) 6 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/BlocksInSingleArg.stat: -------------------------------------------------------------------------------- 1 | preset = IntelliJ 2 | optIn.configStyleArguments = true 3 | newlines.avoidForSimpleOverflow = [toolong] 4 | <<< single arg with curly 5 | println( 6 | for (x <- Nil) yield { 7 | 2 8 | } 9 | ) 10 | >>> 11 | println( 12 | for (x <- Nil) yield { 13 | 2 14 | } 15 | ) 16 | <<< two args 17 | println( 18 | for (x <- Nil) yield { 19 | 2 20 | }, 21 | 234 22 | ) 23 | >>> 24 | println( 25 | for (x <- Nil) yield { 26 | 2 27 | }, 28 | 234 29 | ) 30 | <<< two args 2 31 | println( 32 | println{ 33 | 2 34 | }, 35 | 234 36 | ) 37 | >>> 38 | println( 39 | println { 40 | 2 41 | }, 42 | 234 43 | ) 44 | <<< #593 stay on line 45 | foo( 1) 46 | >>> 47 | foo(1) 48 | <<< #593 break line 49 | object a { 50 | foo("12345678901234567890123456789012345678901234567890123456789012345678901234567890") 51 | } 52 | >>> 53 | object a { 54 | foo("12345678901234567890123456789012345678901234567890123456789012345678901234567890") 55 | } 56 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/Class.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 10 2 | <<< Comment after extends with #672 3 | class A extends B with C{ // this is an additional comment 4 | } 5 | >>> 6 | class A 7 | extends B 8 | with C { // this is an additional comment 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/ContinuationIndent.stat: -------------------------------------------------------------------------------- 1 | indent.callSite = 5 2 | indent.defnSite = 3 3 | indent.extendSite = 2 4 | indent.withSiteRelativeToExtends = 2 5 | maxColumn = 39 6 | <<< #143 7 | def foo( 8 | a: Int, 9 | b: Int 10 | ): Int = { 11 | function( 12 | 2, 13 | 3 14 | ) 15 | } 16 | >>> 17 | def foo( 18 | a: Int, 19 | b: Int 20 | ): Int = { 21 | function( 22 | 2, 23 | 3 24 | ) 25 | } 26 | <<< Extend site 27 | class ExtendTest extends A with B with C with D { self: A with B with C with D with E => 28 | } 29 | >>> 30 | class ExtendTest 31 | extends A 32 | with B 33 | with C 34 | with D { 35 | self: A 36 | with B 37 | with C 38 | with D 39 | with E => 40 | } 41 | <<< comment between inits 42 | maxColumn = 30 43 | indent.withSiteRelativeToExtends = 2 44 | === 45 | class A extends AVeryLongName1 /* comment */ with AVeryLongName2 with AVeryLongName3 46 | >>> 47 | class A 48 | extends AVeryLongName1 /* comment */ 49 | with AVeryLongName2 50 | with AVeryLongName3 51 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/ContinuationIndentHalfDanglingParens.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 6 2 | danglingParentheses = {callSite: true, defnSite: false} 3 | 4 | <<< classes and methods 5 | object Foo3 { 6 | def f(a: A, b: B, c: C) = 1 7 | class F(a: A, b: B, c: C) 8 | 9 | f(a, b, c) 10 | new F(a, b, c) 11 | } 12 | >>> 13 | object Foo3 { 14 | def f( 15 | a: A, 16 | b: B, 17 | c: C) = 18 | 1 19 | class F( 20 | a: A, 21 | b: B, 22 | c: C) 23 | 24 | f( 25 | a, 26 | b, 27 | c 28 | ) 29 | new F( 30 | a, 31 | b, 32 | c 33 | ) 34 | } -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/ContinuationIndentNoDanglingParens.stat: -------------------------------------------------------------------------------- 1 | indent.callSite = 2 2 | indent.defnSite = 4 3 | indent.extendSite = 4 4 | danglingParentheses.preset = false 5 | maxColumn = 50 6 | <<< Type Annotation Site 7 | def doAThingFunction(extremelyLongNamedParameterNumberOne: Int, extremelyLongNamedParameterNumberTwo: Int): ExtremelyLongNameForAReturnValueType 8 | >>> 9 | def doAThingFunction( 10 | extremelyLongNamedParameterNumberOne: Int, 11 | extremelyLongNamedParameterNumberTwo: Int) 12 | : ExtremelyLongNameForAReturnValueType -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/ImportSingleLine.source: -------------------------------------------------------------------------------- 1 | importSelectors = singleLine 2 | <<< break #101 3 | import org.scalajs.dom.experimental.serviceworkers.{ServiceWorkerGlobalScope, ServiceWorkerRegistration} 4 | >>> 5 | import org.scalajs.dom.experimental.serviceworkers.{ServiceWorkerGlobalScope, ServiceWorkerRegistration} 6 | <<< break #101 short 7 | import org.{Aaaaaa, GlobalScope, Registration} 8 | >>> 9 | import org.{Aaaaaa, GlobalScope, Registration} 10 | <<< break #101 short 2 11 | import org.{Aaaa, Bbbbb, C, D, E, F, G, H, I, J, K, L} 12 | >>> 13 | import org.{Aaaa, Bbbbb, C, D, E, F, G, H, I, J, K, L} 14 | <<< undo the work of other import formatters 15 | import org.{ 16 | Aaaa, 17 | Bbbbb, 18 | C, 19 | D 20 | } 21 | >>> 22 | import org.{Aaaa, Bbbbb, C, D} 23 | <<< handle inline comments 24 | import org.{ 25 | // what? 26 | Aaaa, 27 | Bbbbb, 28 | C, 29 | D 30 | } 31 | >>> 32 | import org.{ 33 | // what? 34 | Aaaa, Bbbbb, C, D} 35 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/Issue1509.stat: -------------------------------------------------------------------------------- 1 | maxColumn=41 2 | <<< issue 1509 3 | val x = 4 | if (true) 5 | List() match { 6 | case x :: xs => ??? 7 | case Nil => ??? 8 | } 9 | else { 10 | 2 11 | } 12 | >>> 13 | val x = 14 | if (true) 15 | List() match { 16 | case x :: xs => ??? 17 | case Nil => ??? 18 | } 19 | else { 20 | 2 21 | } -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/NoAlign.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 40 2 | align.openParenDefnSite = true 3 | align.openParenCallSite = false 4 | danglingParentheses.preset = false 5 | <<< single line still works 6 | function(aaaaaaaa, bbbbbbbb) 7 | >>> 8 | function(aaaaaaaa, bbbbbbbb) 9 | <<< no align 10 | function(aaaaaaaaaaaaaaaaaaa, 11 | bbbbbbbbbbbbbbbbbbb) 12 | >>> 13 | function( 14 | aaaaaaaaaaaaaaaaaaa, 15 | bbbbbbbbbbbbbbbbbbb) 16 | <<< align defn site 17 | def function(aaaaaaaaaa: A, 18 | bbbbbbbbbbbbbb: B): C = 2 19 | >>> 20 | def function(aaaaaaaaaa: A, 21 | bbbbbbbbbbbbbb: B): C = 2 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/Type747.stat: -------------------------------------------------------------------------------- 1 | align.openParenDefnSite = false 2 | danglingParentheses.preset = false 3 | <<< #747 4 | type MyTypeWithVeryLongName = (A, 5 | Int, 6 | Int, 7 | Int, 8 | Int, 9 | String, 10 | DateTime, 11 | List[String], 12 | List[String], 13 | Int, 14 | B, 15 | C) 16 | >>> 17 | type MyTypeWithVeryLongName = ( 18 | A, 19 | Int, 20 | Int, 21 | Int, 22 | Int, 23 | String, 24 | DateTime, 25 | List[String], 26 | List[String], 27 | Int, 28 | B, 29 | C) 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/Unicode.stat: -------------------------------------------------------------------------------- 1 | rewriteTokens { 2 | "=>": "⇒" 3 | "<-": "←" 4 | } 5 | <<< confusing unicode symbols 6 | for { 7 | a <- List(1) 8 | } yield (x => 2) 9 | >>> 10 | for { 11 | a ← List(1) 12 | } yield (x ⇒ 2) 13 | <<< #1033 14 | println(s"\u001b[1;${color}m${message}\u001b[m") 15 | >>> 16 | println(s"\u001b[1;${color}m${message}\u001b[m") 17 | <<< #1110 18 | object Foo { 19 | // format: off 20 | val nbsp = "\u00A0" 21 | val test = s"${nbsp}\uc83D" 22 | // format: on 23 | } 24 | >>> 25 | object Foo { 26 | // format: off 27 | val nbsp = "\u00A0" 28 | val test = s"${nbsp}\uc83D" 29 | // format: on 30 | } 31 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/arityThreshold.source: -------------------------------------------------------------------------------- 1 | maxColumn = 80 2 | verticalMultiline = { 3 | atDefnSite = true 4 | arityThreshold = 2 5 | } 6 | indent.defnSite = 2 7 | <<< Verify that verticalMultiline.arityThreshold works as expected 8 | case class Foo(x: String) 9 | case class Bar(x: String, y: String) 10 | case class VeryLongNames(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String) 11 | object A { 12 | def foo(x: String, y: String) 13 | def hello(how: String)(are: String)(you: String) = how + are + you 14 | } 15 | >>> 16 | case class Foo(x: String) 17 | case class Bar( 18 | x: String, 19 | y: String) 20 | case class VeryLongNames( 21 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String) 22 | object A { 23 | def foo( 24 | x: String, 25 | y: String 26 | ) 27 | def hello(how: String)(are: String)(you: String) = how + are + you 28 | } 29 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/i1116.stat: -------------------------------------------------------------------------------- 1 | preset = default 2 | <<< #1116 3 | val x: A# ! 4 | >>> 5 | val x: A# ! 6 | <<< #1116 underscore 7 | val x: A# _a 8 | >>> 9 | val x: A#_a 10 | <<< #1116 letter 11 | val x: A# a 12 | >>> 13 | val x: A#a 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/i1245.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 80 2 | <<< simplified example 3 | a == () :: Nil 4 | >>> 5 | a == () :: Nil 6 | <<< hlist example 7 | "foo" :: () :: true :: HNil 8 | >>> 9 | "foo" :: () :: true :: HNil 10 | <<< should parse () as unit in list construction 11 | object X { 12 | def x = List(()) == () :: Nil 13 | } 14 | >>> 15 | object X { 16 | def x = List(()) == () :: Nil 17 | } 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/i1439.stat: -------------------------------------------------------------------------------- 1 | indentOperator.topLevelOnly = false 2 | <<< unindentTopLevelOperators should not break code blocks 3 | class TestSpec extends FlatSpec with Matchers { 4 | 5 | "Foo" should "do things" in { 6 | def bar: String = "test" 7 | bar should endWith("st") 8 | } 9 | 10 | } 11 | >>> 12 | class TestSpec extends FlatSpec with Matchers { 13 | 14 | "Foo" should "do things" in { 15 | def bar: String = "test" 16 | bar should endWith("st") 17 | } 18 | 19 | } 20 | <<< test 21 | object test { 22 | val x = 1 + { 23 | 2 + 3 24 | } 25 | } 26 | >>> 27 | object test { 28 | val x = 1 + { 29 | 2 + 3 30 | } 31 | } 32 | <<< #1547 33 | it should "test something" in new A { 34 | println(test) } 35 | >>> 36 | it should "test something" in new A { 37 | println(test) 38 | } 39 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/includeNoParensInSelectChains.stat: -------------------------------------------------------------------------------- 1 | includeNoParensInSelectChains = true 2 | <<< include applications without parens in select chains 3 | List(1).toIterator.buffered 4 | .map(_ + 2) 5 | .filter(_ > 2) 6 | >>> 7 | List(1) 8 | .toIterator 9 | .buffered 10 | .map(_ + 2) 11 | .filter(_ > 2) 12 | <<< include applications without parens in select chains 2 13 | List(1) 14 | .toIterator.buffered 15 | .map(_ + 2).filter(_ > 2) 16 | >>> 17 | List(1) 18 | .toIterator 19 | .buffered 20 | .map(_ + 2) 21 | .filter(_ > 2) 22 | <<< don't throw exception (#1407) 23 | object CirceWritable { 24 | implicit def contentTypeOf_CirceJson(): ContentTypeOf[io.circe.Json] = 25 | ContentTypeOf[io.circe.Json](Some(ContentTypes.JSON)) 26 | } 27 | >>> 28 | object CirceWritable { 29 | implicit def contentTypeOf_CirceJson(): ContentTypeOf[io.circe.Json] = 30 | ContentTypeOf[io.circe.Json](Some(ContentTypes.JSON)) 31 | } 32 | <<< include applications without parens at the end of select chains 33 | List(1) 34 | .map(_ + 2) 35 | .filter(_ > 2).toIterator 36 | >>> 37 | List(1) 38 | .map(_ + 2) 39 | .filter(_ > 2) 40 | .toIterator 41 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/test/poorMansTrailingCommasInConfigStyle.stat: -------------------------------------------------------------------------------- 1 | poorMansTrailingCommasInConfigStyle = true 2 | <<< no trailing commas 3 | function( 4 | a, 5 | b, 6 | c 7 | ) 8 | >>> 9 | function( 10 | a 11 | , b 12 | , c 13 | ) 14 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasAlwaysAlignMore.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 35 2 | trailingCommas = always 3 | align.preset = more 4 | <<< should consider comments with extra whitespace when adding trailing commas align more 5 | def method( 6 | abc: String, // abc comment 7 | d: String // d comment 8 | ) = ??? 9 | >>> 10 | def method( 11 | abc: String, // abc comment 12 | d: String, // d comment 13 | ) = ??? 14 | <<< should consider comments when adding trailing comments align more 15 | def method( 16 | a: String, // a comment 17 | b: String // b comment 18 | ) = ??? 19 | >>> 20 | def method( 21 | a: String, // a comment 22 | b: String, // b comment 23 | ) = ??? 24 | 25 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasAlwaysOwners.stat: -------------------------------------------------------------------------------- 1 | trailingCommas = always 2 | 3 | <<< should not add trailing commas when owner is not valid 4 | lst.map { x => 5 | x + 1 6 | } 7 | >>> 8 | lst.map { x => 9 | x + 1 10 | } 11 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasAlwaysSingleLine.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 30 2 | trailingCommas = always 3 | optIn.configStyleArguments = false 4 | 5 | <<< should remove a trailing comma when joining into a single line 6 | foo(a, 7 | b, 8 | ) 9 | >>> 10 | foo(a, b) 11 | 12 | <<< should remove a trailing comma when removing config style 13 | foo( 14 | a, 15 | ) 16 | >>> 17 | foo(a) 18 | <<< #3663 tuple 19 | val x = ( 20 | "a", 21 | "b", 22 | ) 23 | >>> 24 | val x = ("a", "b") 25 | <<< #3663 enclosed literal 26 | val x = ( "a", 27 | ) 28 | >>> 29 | val x = ("a") 30 | <<< #3663 enclosed lambda 31 | val x = ( x => x + 1, 32 | ) 33 | >>> 34 | val x = (x => x + 1) 35 | <<< #3663 enclosed lambda 1 36 | val x = ( 37 | x => x + 1, 38 | ) 39 | >>> 40 | val x = (x => x + 1) 41 | <<< with braces-to-parens rewrite, allowFolding 42 | rewrite.rules = [ RedundantBraces ] 43 | rewrite.trailingCommas.allowFolding = true 44 | rewrite.redundantBraces.parensForOneLineApply = true 45 | === 46 | foo { bar } 47 | >>> 48 | foo(bar) 49 | <<< with braces-to-parens rewrite, !allowFolding 50 | rewrite.rules = [ RedundantBraces ] 51 | rewrite.trailingCommas.allowFolding = false 52 | rewrite.redundantBraces.parensForOneLineApply = true 53 | === 54 | foo { bar } 55 | >>> 56 | foo { bar } 57 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasAlwaysVerticalMultilineAtDefnSite.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 30 2 | trailingCommas = always 3 | verticalMultiline.atDefnSite = true 4 | <<< shouldn't put comma in empty parentheses 5 | case class Test()(a1: Int, a2: Int, a3: Int, a4: Int, a5: Int) 6 | >>> 7 | case class Test( 8 | )(a1: Int, 9 | a2: Int, 10 | a3: Int, 11 | a4: Int, 12 | a5: Int) 13 | 14 | <<< shouldn't put comma in parentheses that contains only comment 15 | case class Test( 16 | // comment 17 | )(a1: Int, a2: Int, a3: Int, a4: Int, a5: Int) 18 | >>> 19 | case class Test( 20 | // comment 21 | )(a1: Int, 22 | a2: Int, 23 | a3: Int, 24 | a4: Int, 25 | a5: Int) 26 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasMultipleAlignMore.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 35 2 | trailingCommas = multiple 3 | align.preset = more 4 | <<< should consider comments with extra whitespace when adding trailing commas align more 5 | def method( 6 | abc: String, // abc comment 7 | d: String // d comment 8 | ) = ??? 9 | >>> 10 | def method( 11 | abc: String, // abc comment 12 | d: String, // d comment 13 | ) = ??? 14 | <<< should consider comments when adding trailing comments align more 15 | def method( 16 | a: String, // a comment 17 | b: String // b comment 18 | ) = ??? 19 | >>> 20 | def method( 21 | a: String, // a comment 22 | b: String, // b comment 23 | ) = ??? 24 | 25 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasNeverComments.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 30 2 | trailingCommas = never 3 | 4 | <<< should consider comments when removing trailing commas 5 | def method( 6 | a: String, 7 | b: String, // a comment 8 | ) 9 | >>> 10 | def method( 11 | a: String, 12 | b: String // a comment 13 | ) 14 | 15 | <<< should consider indented comments on the next line when removing trailing commas 16 | def method( 17 | a: String, 18 | b: String, 19 | // a comment 20 | ) 21 | >>> 22 | def method( 23 | a: String, 24 | b: String 25 | // a comment 26 | ) 27 | 28 | <<< should consider unindented comments on the next line when removing trailing commas 29 | def method( 30 | a: String, 31 | b: String, 32 | // a comment 33 | ) 34 | >>> 35 | def method( 36 | a: String, 37 | b: String 38 | // a comment 39 | ) 40 | <<< preserve the position of comment see #1231 41 | object Test { 42 | def apply() = { 43 | div( 44 | div( 45 | (5 to 5).map { res => 5 }, 46 | // 47 | ) 48 | ) 49 | } 50 | } 51 | >>> 52 | object Test { 53 | def apply() = { 54 | div( 55 | div( 56 | (5 to 5).map { res => 57 | 5 58 | } 59 | // 60 | ) 61 | ) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasNeverCommentsAlignMore.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 35 2 | trailingCommas = never 3 | align.preset = more 4 | 5 | <<< should consider comments when removing trailing commas while align comment 6 | def method( 7 | abc: String, // abc comment 8 | d: String, // d comment 9 | ) 10 | >>> 11 | def method( 12 | abc: String, // abc comment 13 | d: String // d comment 14 | ) 15 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/trailing-commas/trailingCommasNeverSingleLine.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 30 2 | trailingCommas = never 3 | optIn.configStyleArguments = false 4 | 5 | <<< should remove a trailing comma when joining into a single line 6 | foo(a, 7 | b, 8 | ) 9 | >>> 10 | foo(a, b) 11 | 12 | <<< should remove a trailing comma when removing config style 13 | foo( 14 | a, 15 | ) 16 | >>> 17 | foo(a) 18 | <<< #3663 tuple 19 | val x = ( 20 | "a", 21 | "b", 22 | ) 23 | >>> 24 | val x = ("a", "b") 25 | <<< #3663 enclosed literal 26 | val x = ( "a", 27 | ) 28 | >>> 29 | val x = ("a") 30 | <<< #3663 enclosed lambda 31 | val x = ( x => x + 1, 32 | ) 33 | >>> 34 | val x = (x => x + 1) 35 | <<< #3663 enclosed lambda 1 36 | val x = ( 37 | x => x + 1, 38 | ) 39 | >>> 40 | val x = (x => x + 1) 41 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Advanced.source: -------------------------------------------------------------------------------- 1 | 2 | <<< Rich syntax 3 | @ foobar("annot", { 4 | val x = 2 5 | val y = 2 // y=2 6 | x + y 7 | }) 8 | object 9 | a extends b with c { 10 | 11 | def 12 | foo[T: Int#Double#Triple, 13 | R <% String]( 14 | @annot1 15 | x 16 | : Int @annot2 = 2 17 | , y: Int = 3): Int = { 18 | "match" match { 19 | case 1 | 2 => 3 20 | case 2 => 2 21 | } 22 | } 23 | } 24 | >>> 25 | @foobar("annot", { 26 | val x = 2 27 | val y = 2 // y=2 28 | x + y 29 | }) 30 | object a extends b with c { 31 | 32 | def foo[T: Int#Double#Triple, 33 | R <% String]( 34 | @annot1 35 | x: Int @annot2 = 2, 36 | y: Int = 3): Int = { 37 | "match" match { 38 | case 1 | 2 => 3 39 | case 2 => 2 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Basic.source: -------------------------------------------------------------------------------- 1 | 2 | <<< Two methods 3 | object a { 4 | 5 | def one = 1 6 | 7 | def two = 2 } 8 | >>> 9 | object a { 10 | 11 | def one = 1 12 | 13 | def two = 2 14 | } 15 | <<< Two methods, with docstrings 16 | object a { 17 | /** 18 | * One 19 | */ 20 | def one = 1 21 | /** 22 | * Two 23 | */ 24 | def two = 2 } 25 | >>> 26 | object a { 27 | 28 | /** One 29 | */ 30 | def one = 1 31 | 32 | /** Two 33 | */ 34 | def two = 2 35 | } 36 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/ColumnWidth.source: -------------------------------------------------------------------------------- 1 | 2 | <<< Object definition fits in one line 3 | @foobar 4 | object a {val x:Int=1} 5 | >>> 6 | @foobar 7 | object a { val x: Int = 1 } 8 | <<< Object almost fits in one line 9 | object Aaaaaaa { val x12345678: Int = 1 } 10 | >>> 11 | object Aaaaaaa { 12 | val x12345678: Int = 1 13 | } 14 | <<< Indentation is included for penalty 15 | object aaaaaaaaaaaaaaaaaaaaaaaaaaaaa { 16 | val bbbbbbbbbbbbbbbbbbbbbbbbbbbb = 1; 17 | aaa } 18 | >>> 19 | object aaaaaaaaaaaaaaaaaaaaaaaaaaaaa { 20 | val bbbbbbbbbbbbbbbbbbbbbbbbbbbb = 1; 21 | aaa 22 | } 23 | <<< Multiline object definition 24 | @foobar object LoooooooooooongNaaame { val x: Int = 1 } 25 | >>> 26 | @foobar object LoooooooooooongNaaame { 27 | val x: Int = 1 28 | } 29 | <<< One-liner object contains no newlines 30 | object Object { function_____________() } 31 | >>> 32 | object Object { 33 | function_____________() 34 | } 35 | <<< One single-line, one multiline 36 | object Object { object Object______ { } } 37 | >>> 38 | object Object { 39 | object Object______ {} 40 | } 41 | <<< Multiline, single-line, multiline 42 | object Object { 43 | 44 | object A { a } 45 | object B_________________________ { b123456 } 46 | } 47 | >>> 48 | object Object { 49 | 50 | object A { a } 51 | object B_________________________ { 52 | b123456 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Cond.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< Split on = 3 | def better(other: State): Boolean = this.cost <= other.cost && 4 | this.indentation <= other.indentation 5 | >>> 6 | def better(other: State): Boolean = 7 | this.cost <= other.cost && 8 | this.indentation <= other.indentation 9 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Dialect.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< trailing comma 3 | foo( 4 | 1, 5 | 2, 6 | ) 7 | >>> 8 | foo( 9 | 1, 10 | 2 11 | ) 12 | <<< literal types 13 | val x : 42 = 42 14 | >>> 15 | val x: 42 = 42 16 | <<< intersection types 17 | val x : A & B = 42 18 | >>> 19 | val x: A & B = 42 20 | <<< class param 21 | class T(a : Int) 22 | >>> 23 | class T(a: Int) 24 | <<< underscore separator 25 | val x = 1_000_000 26 | >>> 27 | val x = 1_000_000 28 | <<< by name implicit 29 | def foo(implicit x: => Int) = x 30 | >>> 31 | def foo(implicit x: => Int) = x 32 | <<< #2071 given not kw 33 | object Main { 34 | val given = 42 35 | } 36 | >>> 37 | object Main { 38 | val given = 42 39 | } 40 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Lit.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< long 3 | 1l 4 | >>> 5 | 1L 6 | <<< long ok 7 | 1L 8 | >>> 9 | 1L 10 | <<< float 11 | 1F 12 | >>> 13 | 1f 14 | <<< float ok 15 | 1f 16 | >>> 17 | 1f 18 | <<< double 19 | 1D 20 | >>> 21 | 1d 22 | <<< double ok 23 | 1d 24 | >>> 25 | 1d 26 | <<< hex long 27 | 0xFFFFFFFFl 28 | >>> 29 | 0xffffffffL 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Markdown.source: -------------------------------------------------------------------------------- 1 | # 2 | <<< #3672 1 unindented 3 | ```scala mdoc 4 | //> using dep io.scalaland::chimney::{{ git.tag or local.tag }} 5 | import io.scalaland.chimney.Transformer 6 | 7 | case class Foo (a : String) 8 | ``` 9 | >>> a.md 10 | ```scala mdoc 11 | //> using dep io.scalaland::chimney::{{ git.tag or local.tag }} 12 | import io.scalaland.chimney.Transformer 13 | 14 | case class Foo(a: String) 15 | ``` 16 | <<< #3672 2 indented 17 | * example inside a bullet point list: 18 | ```scala mdoc 19 | //> using dep io.scalaland::chimney::{{ git.tag or local.tag }} 20 | import io.scalaland.chimney.Transformer 21 | 22 | case class Foo (a : String) 23 | ``` 24 | >>> a.md 25 | * example inside a bullet point list: 26 | ```scala mdoc 27 | //> using dep io.scalaland::chimney::{{ git.tag or local.tag }} 28 | import io.scalaland.chimney.Transformer 29 | 30 | case class Foo(a: String) 31 | ``` 32 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Mod.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< private this #94 3 | private[this] val root = 1 4 | >>> 5 | private[this] val root = 1 6 | <<< protected this 7 | protected[this] val root = 1 8 | >>> 9 | protected[this] val root = 1 10 | <<< private ident 11 | private[Enclosing] val root = 1 12 | >>> 13 | private[Enclosing] val root = 1 14 | <<< protected ident 15 | protected[Enclosing] val root = 1 16 | >>> 17 | protected[Enclosing] val root = 1 18 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Symbol.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< symbols get space 3 | def unary_! : Boolean = !value 4 | >>> 5 | def unary_! : Boolean = !value 6 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Template.source: -------------------------------------------------------------------------------- 1 | 2 | <<< extends 3 | class A( 4 | b: B) 5 | extends C 6 | >>> 7 | class A(b: B) extends C 8 | <<< extends with 9 | class A( 10 | b: B) 11 | extends C 12 | with D 13 | >>> 14 | class A(b: B) extends C with D 15 | <<< extends with overflows columns 16 | class A(b: B) extends C___________ with D 17 | >>> 18 | class A(b: B) 19 | extends C___________ 20 | with D 21 | <<< Looong extends, no inline 22 | class A(b: B) extends C with D with E with F with G { 23 | def x = 2 24 | } 25 | >>> 26 | class A(b: B) 27 | extends C 28 | with D 29 | with E 30 | with F 31 | with G { 32 | def x = 2 33 | } 34 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/TermUpdate.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< one arg 3 | sieve(1) = false 4 | >>> 5 | sieve(1) = false 6 | <<< multiple args 7 | sieve(1, 2, 3) = false 8 | >>> 9 | sieve(1, 2, 3) = false 10 | <<< one arg one line 11 | sieve(1, // aaaaaaaaaaaaaaaaaa 12 | 2, 13 | 3) = false 14 | >>> 15 | sieve(1, // aaaaaaaaaaaaaaaaaa 16 | 2, 17 | 3) = false 18 | <<< it's like assignment #204 19 | property("EndsWith") = checkArbitraryRefType[Refined, String, EndsWith[W.`"abc"`.T]] 20 | >>> 21 | property("EndsWith") = 22 | checkArbitraryRefType[ 23 | Refined, 24 | String, 25 | EndsWith[W.`"abc"`.T]] 26 | <<< term.assign #204 27 | property = checkArbitraryRefTypeaaaaaaaaaaaaaa[Refined, String, EndsWith[W.`"abc"`.T]] 28 | >>> 29 | property = 30 | checkArbitraryRefTypeaaaaaaaaaaaaaa[ 31 | Refined, 32 | String, 33 | EndsWith[W.`"abc"`.T]] 34 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/Trait.source: -------------------------------------------------------------------------------- 1 | 2 | <<< trait start new lines 3 | object A { 4 | val x = 1; 5 | trait B { 6 | type X = Int 7 | } 8 | class C extends B 9 | } 10 | >>> 11 | object A { 12 | val x = 1; 13 | trait B { 14 | type X = Int 15 | } 16 | class C extends B 17 | } 18 | <<< mod protected 19 | protected [scalafmt] sealed trait UnitTestStyle 20 | >>> 21 | protected[scalafmt] sealed trait UnitTestStyle 22 | <<< self type 23 | trait Cap extends Util { self => 24 | object Foo { 25 | x 26 | } 27 | 28 | val x: Int => Int = { y => 29 | y + 1 30 | } 31 | } 32 | >>> 33 | trait Cap extends Util { self => 34 | object Foo { 35 | x 36 | } 37 | 38 | val x: Int => Int = { y => 39 | y + 1 40 | } 41 | } 42 | <<< #370 43 | trait SampleTrait extends A with B with C with D with E{ 44 | self: LongNameMixin with B with C with D with EEEEEEEEE => 45 | 46 | def foo: Boolean = true 47 | } 48 | >>> 49 | trait SampleTrait 50 | extends A 51 | with B 52 | with C 53 | with D 54 | with E { 55 | self: LongNameMixin 56 | with B 57 | with C 58 | with D 59 | with EEEEEEEEE => 60 | 61 | def foo: Boolean = true 62 | } 63 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/TypeArgument.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< One argument per line 3 | object Object { 4 | val x = function[a1234567, b1234567, 5 | c1234567, d1234567] 6 | val y = 2 // indented correctly 7 | } 8 | >>> 9 | object Object { 10 | val x = function[a1234567, 11 | b1234567, 12 | c1234567, 13 | d1234567] 14 | val y = 2 // indented correctly 15 | } 16 | <<< Single line with newline at start 17 | object a { 18 | function[aaaaaaaaaaaaaa, aaaaaaaaaaaaaa]() 19 | } 20 | >>> 21 | object a { 22 | function[aaaaaaaaaaaaaa, 23 | aaaaaaaaaaaaaa]() 24 | } 25 | <<< One line one arg at 4 indent 26 | object a { 27 | function[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 28 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] 29 | } 30 | >>> 31 | object a { 32 | function[ 33 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 34 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] 35 | } 36 | <<< Type args and args different policy 37 | object Object { 38 | val x = function[a1234567, b1234567](a) 39 | } 40 | >>> 41 | object Object { 42 | val x = 43 | function[a1234567, b1234567](a) 44 | } 45 | <<< Pat.Type.Apply 46 | x match { 47 | case c: Eval.Compute [A] => 48 | } 49 | >>> 50 | x match { 51 | case c: Eval.Compute[A] => 52 | } 53 | 54 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/unit/UnaryApply.stat: -------------------------------------------------------------------------------- 1 | 2 | <<< literal 3 | -100 4 | 5 | >>> 6 | -100 7 | <<< ident 8 | -a 9 | >>> 10 | -a 11 | <<< this 12 | -this.foo 13 | >>> 14 | -this.foo 15 | <<< Tuple with first unary 16 | ( -this.cost, this.splits.length, 17 | -this.indentation) 18 | >>> 19 | (-this.cost, 20 | this.splits.length, 21 | -this.indentation) 22 | <<< bang 23 | ( 24 | !right.isInstanceOf[Comment]) 25 | >>> 26 | (!right.isInstanceOf[Comment]) 27 | <<< #697 you shall not change AST!! 28 | def =!=(that: S): Boolean = ! ===(that) 29 | >>> 30 | def =!=(that: S): Boolean = ! ===(that) 31 | <<< #710 you shall not add unneeded space!! 32 | if (!_member) Some(x) else None 33 | >>> 34 | if (!_member) Some(x) else None 35 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/vertical-multiline/newlineAfterOpenParen.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 80 2 | indent.defnSite = 2 3 | verticalMultiline = { 4 | atDefnSite = true 5 | arityThreshold = 2 // Used here to force reformatting. 6 | newlineAfterOpenParen = true 7 | } 8 | danglingParentheses.exclude = [] 9 | newlines.implicitParamListModifierForce=[after] 10 | <<< It should force a newline after open paren. 11 | def other(a: String, b: String)(c: String) = a + b + c 12 | >>> 13 | def other( 14 | a: String, 15 | b: String 16 | )( 17 | c: String 18 | ) = a + b + c 19 | 20 | <<< It should still respect newlines.implicitParamListModifierForce=[after] 21 | def other[T](a: String, b: String)(implicit c: Parse[T]) = a + b + c 22 | >>> 23 | def other[T]( 24 | a: String, 25 | b: String 26 | )(implicit 27 | c: Parse[T] 28 | ) = a + b + c 29 | 30 | <<< newlineAfterOpenParen should only act on definitions (not on invocations in the definitions) 31 | def executeQuery(query: Document, vars: Json = Json.obj()): Json 32 | >>> 33 | def executeQuery( 34 | query: Document, 35 | vars: Json = Json.obj() 36 | ): Json 37 | 38 | <<< Another case of the one above 39 | def executeQuery(query: Document, vars: Thing = Thing(a,b,c)): Json 40 | >>> 41 | def executeQuery( 42 | query: Document, 43 | vars: Thing = Thing(a, b, c) 44 | ): Json 45 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalMultilineDangling.source: -------------------------------------------------------------------------------- 1 | maxColumn = 80 2 | indent.defnSite = 2 3 | verticalMultiline = { 4 | atDefnSite = true 5 | arityThreshold = 2 6 | } 7 | danglingParentheses.exclude = [] 8 | <<< Verify that it respects dangling parens options 9 | sealed trait Foobar 10 | case class Foo(x: String) extends Foobar 11 | case class Bar(x: String, y: String) extends Foobar 12 | case class VeryLongNames(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String) 13 | case class X1() 14 | case class X2(x: Int, y: Int) { def hello: String = "Hello" } 15 | >>> 16 | sealed trait Foobar 17 | case class Foo(x: String) extends Foobar 18 | case class Bar( 19 | x: String, 20 | y: String 21 | ) extends Foobar 22 | case class VeryLongNames( 23 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: String 24 | ) 25 | case class X1() 26 | case class X2( 27 | x: Int, 28 | y: Int 29 | ) { def hello: String = "Hello" } 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/vertical-multiline/verticalMultilineDefnSiteNoDangling.stat: -------------------------------------------------------------------------------- 1 | maxColumn = 40 2 | danglingParentheses.preset = false 3 | verticalMultiline.atDefnSite = true 4 | <<< handles comment correctly 5 | case class Example( 6 | a: Example, 7 | b: Example, 8 | c: Example, 9 | d: Example // Comment 10 | ) 11 | >>> 12 | case class Example( 13 | a: Example, 14 | b: Example, 15 | c: Example, 16 | d: Example // Comment 17 | ) 18 | <<< leaves things alone if you move the ) 19 | case class Example( 20 | a: Example, 21 | b: Example, 22 | c: Example, 23 | d: Example) // Comment 24 | >>> 25 | case class Example( 26 | a: Example, 27 | b: Example, 28 | c: Example, 29 | d: Example) // Comment 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/resources/vertical-multiline/withSpacesInParentheses.stat: -------------------------------------------------------------------------------- 1 | spaces.inParentheses = true 2 | maxColumn = 40 3 | verticalMultiline.atDefnSite = true 4 | <<< def 5 | def x(foo: Int) = 2 6 | >>> 7 | def x( foo: Int ) = 2 8 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/CustomStructureTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import scala.meta._ 4 | import scala.meta.internal.parsers.ScalametaParser 5 | 6 | import munit.FunSuite 7 | 8 | class CustomStructureTest extends FunSuite { 9 | 10 | private def check(original: String, expected: Tree, dialect: Dialect)(implicit 11 | loc: munit.Location, 12 | ): Unit = { 13 | val parser = new ScalametaParser(Input.String(original))(dialect) 14 | assertNoDiff(parser.parseStat().structure, expected.structure) 15 | } 16 | 17 | // #3634 18 | check( 19 | """| 20 | |def foo(a: Foo[_]): Unit = ??? 21 | | """.stripMargin, 22 | Defn.Def( 23 | Nil, 24 | Term.Name("foo"), 25 | List(Member.ParamClauseGroup( 26 | Type.ParamClause(Nil), 27 | List(Term.ParamClause( 28 | List(Term.Param( 29 | Nil, 30 | Term.Name("a"), 31 | Some(Type.Apply( 32 | Type.Name("Foo"), 33 | Type.ArgClause(List(Type.Wildcard(Type.Bounds(None, None)))), 34 | )), 35 | None, 36 | )), 37 | None, 38 | )), 39 | )), 40 | Some(Type.Name("Unit")), 41 | Term.Name("???"), 42 | ), 43 | dialects.Scala3, 44 | ) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/FidelityTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | import org.scalafmt.sysops.FileOps 5 | import org.scalafmt.sysops.PlatformFileOps 6 | import org.scalafmt.util.FormatAssertions 7 | 8 | import scala.meta.dialects.Scala213 9 | 10 | import java.io.File 11 | 12 | import munit.FunSuite 13 | 14 | /** Asserts formatter does not alter original source file's AST. 15 | * 16 | * Will maybe use scalacheck someday. 17 | */ 18 | class FidelityTest extends FunSuite with FormatAssertions { 19 | 20 | private val denyList = Set( 21 | "ConfigReader.scala", 22 | "BuildTime.scala", 23 | "GitCommit.scala", 24 | "/target/", 25 | "/resources/", 26 | "/gh-pages/", 27 | ).map(_.replace("/", File.separator)) 28 | 29 | FileOps.listFiles(".").foreach { x => 30 | val filename = x.toString 31 | val ok = filename.endsWith(".scala") && !denyList.exists(filename.contains) 32 | if (ok) test(filename)( 33 | PlatformFileOps.readFileAsync(x).map { code => 34 | val formatted = Scalafmt 35 | .formatCode(code, ScalafmtConfig.default, filename = filename) 36 | assertFormatPreservesAst(filename, code, formatted.get)( 37 | scala.meta.parsers.Parse.parseSource, 38 | Scala213, 39 | ) 40 | }(munitExecutionContext), 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/RangeTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import org.scalafmt.util.HasTests 4 | 5 | import munit.FunSuite 6 | 7 | class RangeTest extends FunSuite { 8 | test("range preserves indent") { 9 | val original = 10 | """|object a { 11 | |val x = 1 12 | |val y = 2 13 | |} 14 | | """.stripMargin 15 | val expected = 16 | """|object a { 17 | |val x = 1 18 | | val y = 2 19 | |} 20 | | """.stripMargin 21 | val obtained = Scalafmt 22 | .format(original, HasTests.unitTest40, range = Set(Range(2, 2).inclusive)) 23 | .get 24 | assertNoDiff(obtained, expected) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/UnitTests.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt 2 | 3 | import org.scalafmt.sysops.FileOps 4 | import org.scalafmt.util.DiffTest 5 | import org.scalafmt.util.HasTests 6 | 7 | import java.nio.file.Path 8 | 9 | object UnitTests extends HasTests { 10 | import FileOps._ 11 | 12 | /** Avoids parsing all files if some tests are marked ONLY. 13 | */ 14 | def getTestFiles: Seq[String] = { 15 | val testsFiles = listFiles(testDir).map(_.toString) 16 | .filter(filename2parse(_).isDefined) 17 | val onlyTests = testsFiles.filter(_.contains("\n<<< ONLY")) 18 | if (onlyTests.nonEmpty) onlyTests else testsFiles 19 | } 20 | 21 | // TODO(olafur) make possible to limit states per unit test. 22 | override lazy val tests: Seq[DiffTest] = { 23 | def checkPath(p: Path) = filename2parse(p.toString).isDefined 24 | for { 25 | filename <- listFiles((p, a) => checkPath(p) && a.isRegularFile)(testDir) 26 | test <- parseDiffTests(filename, notOnly = sys.env.contains("CI")) 27 | } yield test 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/config/AvoidInfixSettingsTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | class AvoidInfixSettingsTest extends munit.FunSuite { 4 | 5 | Seq(Nil, Seq("foo"), Seq("cross"), Seq("cross", "foo")).foreach { extra => 6 | test(s"AvoidInfixSettings.forSbtOpt: [${extra.mkString(",")}]") { 7 | val settings = AvoidInfixSettings.default 8 | .withExtraExclude(extra.map(AvoidInfixSettings.Filter.apply)) 9 | .getOrElse(AvoidInfixSettings.default) 10 | settings.forSbtOpt match { 11 | case None => 12 | if (!extra.contains("cross")) fail("forSbtOpt shouldn't be None") 13 | case Some(sbtSettings) => 14 | val expected = settings.excludeFilters :+ 15 | AvoidInfixSettings.Filter("cross") 16 | assertEquals(sbtSettings.excludeFilters, expected) 17 | } 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/config/RunnerSettingsTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.config 2 | 3 | import scala.meta._ 4 | 5 | import munit.FunSuite 6 | 7 | class RunnerSettingsTest extends FunSuite { 8 | test("sbt dialect supports trailing commas")( 9 | RunnerSettings.sbt.getDialect( 10 | """| 11 | |lazy 12 | |val x = project( 13 | | a, 14 | | 15 | | 16 | | b, 17 | |) 18 | | """.stripMargin, 19 | ).parse[Source].get, 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/package.scala: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | import munit.diff.DiffOptions 4 | 5 | package object scalafmt { 6 | implicit val diffOptions: DiffOptions = DiffOptions.withShowLines(true) 7 | .withContextSize(10) 8 | } 9 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/GitInfo.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | import scala.util.Try 4 | 5 | // Name and email is registered anyway in the git log. 6 | 7 | case class GitInfo(name: String, email: String, branch: String, commit: String) 8 | 9 | object GitInfo { 10 | 11 | def exec(args: String*): String = { 12 | import sys.process._ 13 | Try(args.!!.trim).getOrElse("ERROR") 14 | } 15 | 16 | lazy val user: String = exec("git", "config", "--get", "user.name") 17 | 18 | lazy val email: String = exec("git", "config", "--get", "user.email") 19 | 20 | val travis: Option[GitInfo] = for { 21 | isCi <- sys.env.get("CI") if isCi == "true" 22 | } yield GitInfo("CI", "CI", currentBranch, currentCommit) 23 | 24 | def apply(): GitInfo = travis 25 | .getOrElse(GitInfo(user, email, currentBranch, currentCommit)) 26 | 27 | def currentCommit = exec("git", "rev-parse", "HEAD") 28 | 29 | def currentBranch = exec("git", "rev-parse", "--abbrev-ref", "HEAD") 30 | } 31 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/JavaInfo.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | case class JavaInfo(name: String, vendor: String, version: String) 4 | 5 | object JavaInfo { 6 | 7 | def apply(): JavaInfo = JavaInfo( 8 | sys.props("java.vm.name"), 9 | sys.props("java.vm.vendor"), 10 | sys.props("java.vm.version"), 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/MachineStats.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | case class MachineStats( 4 | javaInfo: JavaInfo, 5 | osInfo: OsInfo, 6 | runtimeInfo: RuntimeInfo, 7 | gitInfo: GitInfo, 8 | ) 9 | 10 | object MachineStats { 11 | 12 | def apply(): MachineStats = 13 | MachineStats(JavaInfo(), OsInfo(), RuntimeInfo(), GitInfo()) 14 | } 15 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/OsInfo.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | case class OsInfo(name: String, architecture: String, version: String) 4 | 5 | object OsInfo { 6 | 7 | def apply(): OsInfo = 8 | OsInfo(sys.props("os.name"), sys.props("os.arch"), sys.props("os.version")) 9 | } 10 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/RuntimeInfo.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | case class RuntimeInfo( 4 | availableProcessor: Int, 5 | maxMemory: Long, 6 | totalMemory: Long, 7 | ) 8 | 9 | object RuntimeInfo { 10 | 11 | def apply(): RuntimeInfo = { 12 | val runtime = Runtime.getRuntime 13 | RuntimeInfo( 14 | runtime.availableProcessors(), 15 | runtime.maxMemory(), 16 | runtime.totalMemory(), 17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/stats/TestStats.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.stats 2 | 3 | import org.scalafmt.util.Result 4 | 5 | import java.util.Date 6 | 7 | case class TestStats( 8 | createdAt: Long, 9 | results: Seq[Result], 10 | javaInfo: JavaInfo, 11 | osInfo: OsInfo, 12 | runtimeInfo: RuntimeInfo, 13 | gitInfo: GitInfo, 14 | ) { 15 | 16 | def shortInfo: String = s"TestStats(created=${new Date(createdAt)}," + 17 | s"commit=${gitInfo.commit})" 18 | 19 | def shortCommit: String = gitInfo.commit.take(6) 20 | 21 | def intersectResults(other: TestStats): Seq[(Result, Result)] = { 22 | val resultByName = other.results.map(x => x.test.fullName -> x).toMap 23 | results.collect { 24 | case r if resultByName.contains(r.test.fullName) => 25 | r -> resultByName(r.test.fullName) 26 | } 27 | } 28 | } 29 | 30 | object TestStats { 31 | 32 | def apply(results: Seq[Result]): TestStats = TestStats( 33 | System.currentTimeMillis(), 34 | results, 35 | JavaInfo(), 36 | OsInfo(), 37 | RuntimeInfo(), 38 | GitInfo(), 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/util/CanRunTests.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | import org.scalafmt.Error 4 | 5 | import scala.meta.parsers.ParseException 6 | 7 | import munit.FunSuite 8 | import munit.Location 9 | 10 | trait CanRunTests extends FunSuite with HasTests { 11 | def runTest(run: DiffTest => Unit)(t: DiffTest): Unit = { 12 | implicit val loc: Location = t.loc 13 | val paddedName = f"${t.fullName}%-70s|" 14 | 15 | if (ignore(t)) { 16 | // Not even ignore(t), save console space. 17 | } else if (t.skip) test(paddedName.ignore) {} 18 | else test(paddedName)( 19 | try run(t) 20 | catch { 21 | case Error.WithCode(e: ParseException, code) => 22 | fail("test does not parse\n" + parseException2Message(e, code), e) 23 | }, 24 | ) 25 | } 26 | 27 | def runTestsDefault(): Unit = testsToRun.foreach(runTest(defaultRun)) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/util/DiffTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | import org.scalafmt.config.ScalafmtConfig 4 | import org.scalafmt.sysops.AbsoluteFile 5 | import org.scalafmt.sysops.PlatformCompat 6 | import org.scalafmt.tests.BuildInfo 7 | 8 | import munit.Location 9 | 10 | case class DiffTest( 11 | name: String, 12 | filename: String, 13 | loc: Location, 14 | original: String, 15 | expected: String, 16 | skip: Boolean, 17 | only: Boolean, 18 | style: ScalafmtConfig, 19 | stateVisits: Option[Int] = None, 20 | stateVisits2: Option[Int] = None, 21 | ) { 22 | val file = PlatformCompat 23 | .relativize(AbsoluteFile(DiffTest.testDir), AbsoluteFile(loc.path)) 24 | val fullName = s"$file:${loc.line}: $name" 25 | } 26 | 27 | object DiffTest { 28 | val testDir = BuildInfo.resourceDirectory 29 | } 30 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/util/ErrorTest.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | import org.scalafmt.Formatted 4 | import org.scalafmt.Scalafmt 5 | 6 | import munit.FunSuite 7 | 8 | class ErrorTest extends FunSuite { 9 | private val nonSourceFile = Seq("class A {", "val x + 1", "println 1") 10 | nonSourceFile.foreach(original => 11 | test(s"errors are caught: $original")( 12 | Scalafmt.format(original, HasTests.unitTest40) match { 13 | case _: Formatted.Success => fail("expected failure, got success") 14 | case _ => 15 | }, 16 | ), 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/util/FormatOutput.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | case class FormatOutput(token: String, visits: Int) 4 | -------------------------------------------------------------------------------- /scalafmt-tests/shared/src/test/scala/org/scalafmt/util/Result.scala: -------------------------------------------------------------------------------- 1 | package org.scalafmt.util 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | case class Result( 6 | test: DiffTest, 7 | obtained: String, 8 | obtainedHtml: String, 9 | tokens: Seq[FormatOutput], 10 | maxVisitsOnSingleToken: Int, 11 | visitedStates: Int, 12 | timeNs: Long, 13 | ) { 14 | 15 | def title = f"${test.name} (${timeMs}ms, $visitedStates states)" 16 | 17 | def timeMs = TimeUnit.MILLISECONDS.convert(timeNs, TimeUnit.NANOSECONDS) 18 | 19 | def statesPerMs: Long = visitedStates / timeMs 20 | } 21 | -------------------------------------------------------------------------------- /scalafmt.ps1: -------------------------------------------------------------------------------- 1 | &java -jar "$pwd\scalafmt" $args -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | lib/core/metadata.js 2 | lib/core/MetadataBlog.js 3 | 4 | translated_docs 5 | build/ 6 | yarn.lock 7 | node_modules 8 | i18n/* 9 | !i18n/en.json 10 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "examples": "docusaurus-examples", 4 | "start": "docusaurus-start", 5 | "build": "docusaurus-build", 6 | "publish-gh-pages": "docusaurus-publish", 7 | "write-translations": "docusaurus-write-translations", 8 | "version": "docusaurus-version", 9 | "rename-version": "docusaurus-rename-version" 10 | }, 11 | "devDependencies": { 12 | "docusaurus": "^1.11.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /website/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": { 3 | "Documentation": [ 4 | "installation", 5 | "configuration", 6 | "gotchas", 7 | "faq", 8 | "known-issues", 9 | "changelog" 10 | ], 11 | "Contributing": ["contributing-scalafmt", "contributing-website"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /website/static/css/code-blocks-buttons.css: -------------------------------------------------------------------------------- 1 | /* "Copy" code block button */ 2 | pre { 3 | position: relative; 4 | } 5 | 6 | pre .btnIcon, 7 | pre .btnCompare { 8 | position: absolute; 9 | top: 4px; 10 | z-index: 2; 11 | cursor: pointer; 12 | border: 1px solid transparent; 13 | padding: 0; 14 | color: #000; 15 | background-color: transparent; 16 | height: 30px; 17 | transition: all .25s ease-out; 18 | } 19 | 20 | pre .btnIcon:hover, 21 | pre .btnCompare:hover { 22 | text-decoration: none; 23 | } 24 | 25 | .btnIcon__body, 26 | .btnCompare__body { 27 | align-items: center; 28 | display: flex; 29 | } 30 | 31 | .btnIcon svg { 32 | fill: currentColor; 33 | margin-right: .4em; 34 | } 35 | 36 | .btnIcon__label, 37 | .btnCompare__label { 38 | font-size: 11px; 39 | } 40 | 41 | .btnClipboard, 42 | .btnCompare { 43 | right: 10px; 44 | } 45 | -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/scalameta-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalameta/scalafmt/8d0acfe5c4ab10216a0f9fb650e1198e59c80fae/website/static/img/scalameta-logo.png -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "prettier@2.0.4": 6 | "integrity" "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==" 7 | "resolved" "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz" 8 | "version" "2.0.4" 9 | --------------------------------------------------------------------------------