diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..e565cf45 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,5 @@ +# Commits listed here are skipped by `git blame` (bulk reformats, etc.). +# Enable locally with: git config blame.ignoreRevsFile .git-blame-ignore-revs + +# Reformat with scalafmt 3.11.1 +2e0458a04993c5d35625ad52fec79604df5db32f diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 00000000..d1eb9f45 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,105 @@ +//description of properties: https://scalameta.org/scalafmt/docs/configuration.html +version = "3.11.1" +runner.dialect = scala213 +maxColumn = 120 + +continuationIndent { + defnSite = 2 + ctorSite = 2 + extendSite = 2 + withSiteRelativeToExtends = 2 +} + +align.preset = none + +binPack { + parentConstructors = OnelineIfPrimaryOneline + literalsSingleLine = false +} + +newlines { + alwaysBeforeMultilineDef = false + afterCurlyLambda = preserve + implicitParamListModifierPrefer = after + penalizeSingleSelectMultiArgList = false + avoidForSimpleOverflow = [punct, tooLong] + afterInfix = some +} + +# RedundantParens is omitted (vs. the shared AVSystem config): scex is an existential-type-heavy +# codebase and the rule strips parens that are syntactically required around `T forSome { ... }` +# types in lambda-parameter ascriptions, producing code that no longer parses. +rewrite.rules = [AvoidInfix, SortModifiers, SortImports, PreferCurlyFors, RedundantBraces] +rewrite.sortModifiers.order = ["override", "private", "protected", "implicit", "final", "sealed", "abstract", "lazy"] +rewrite.redundantBraces { + stringInterpolation = true + generalExpressions = false + methodBodies = true + includeUnitMethods = false + parensForOneLineApply = true +} + +trailingCommas = multiple +importSelectors = singleLine + +optIn { + breakChainOnFirstMethodDot = false + # - if newlines.source is missing or keep: + # - if true, will keep existing line breaks around annotations + # - if newlines.source is fold: + # - if true, will break before the entity being annotatated + # - will not force break between consecutive annotations + # - if newlines.source is unfold: + # - if true, will break between consecutive annotations + # - will always break before the entity being annotatated + annotationNewlines = false +} + +rewrite.neverInfix.excludeFilters = [ + until + to + by + eq + ne + "should.*" + "contain.*" + "must.*" + in + ignore + be + taggedAs + thrownBy + synchronized + have + when + size + only + noneOf + oneElementOf + noElementsOf + atLeastOneElementOf + atMostOneElementOf + allElementsOf + inOrderElementsOf + theSameElementsAs + //below extends default + theSameElementsInOrderAs + like + zip + orElse + getOrElse + matchOpt + map + flatMap +] + +xmlLiterals.assumeFormatted = true +project.git = true +danglingParentheses.exclude = [ + // "class", //with that, trailling comma don't work in class definition + "trait" +] +verticalMultiline { + atDefnSite = true + newlineAfterOpenParen = true +} diff --git a/build.sbt b/build.sbt index 1db3f3ff..038763f4 100644 --- a/build.sbt +++ b/build.sbt @@ -1,22 +1,26 @@ name := "scex" -inThisBuild(Seq( - organization := "com.avsystem.scex", - scalaVersion := "2.13.18", - githubWorkflowTargetTags ++= Seq("v*"), - githubWorkflowJavaVersions := Seq(JavaSpec.temurin("17"), JavaSpec.temurin("21"), JavaSpec.temurin("25")), - githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))), - - githubWorkflowPublish := Seq(WorkflowStep.Sbt( - List("ci-release"), - env = Map( - "PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}", - "PGP_SECRET" -> "${{ secrets.PGP_SECRET }}", - "SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}", - "SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}" - ) - )), -)) +inThisBuild( + Seq( + organization := "com.avsystem.scex", + scalaVersion := "2.13.18", + githubWorkflowTargetTags ++= Seq("v*"), + githubWorkflowJavaVersions := Seq(JavaSpec.temurin("17"), JavaSpec.temurin("21"), JavaSpec.temurin("25")), + githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))), + + githubWorkflowPublish := Seq( + WorkflowStep.Sbt( + List("ci-release"), + env = Map( + "PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}", + "PGP_SECRET" -> "${{ secrets.PGP_SECRET }}", + "SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}", + "SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}", + ), + ) + ), + ) +) val CompileAndTest = "compile->compile;test->test" @@ -38,8 +42,9 @@ lazy val subprojectSettings = Seq( crossVersion := CrossVersion.full, javacOptions ++= Seq( - "--release", "17", - "-parameters" + "--release", + "17", + "-parameters", ), scalacOptions ++= Seq( @@ -51,12 +56,12 @@ lazy val subprojectSettings = Seq( "-language:dynamics", "-language:experimental.macros", "-Xfatal-warnings", - "-Xlint:-missing-interpolator,-adapted-args,-unused,_" + "-Xlint:-missing-interpolator,-adapted-args,-unused,_", ), scalacOptions ++= Seq( "-Xnon-strict-patmat-analysis", - "-Xlint:-strict-unsealed-patmat" + "-Xlint:-strict-unsealed-patmat", ), projectInfo := ModuleInfo( @@ -66,14 +71,16 @@ lazy val subprojectSettings = Seq( startYear = Some(2015), organizationName = "AVSystem", organizationHomepage = Some(url("http://www.avsystem.com/")), - scmInfo = Some(ScmInfo( - browseUrl = url("https://github.com/AVSystem/scex.git"), - connection = "scm:git:git@github.com:AVSystem/scex.git", - devConnection = Some("scm:git:git@github.com:AVSystem/scex.git") - )), + scmInfo = Some( + ScmInfo( + browseUrl = url("https://github.com/AVSystem/scex.git"), + connection = "scm:git:git@github.com:AVSystem/scex.git", + devConnection = Some("scm:git:git@github.com:AVSystem/scex.git"), + ) + ), licenses = Vector(License.MIT), developers = Vector( - Developer("ddworak", "Dawid Dworak", "d.dworak@avsystem.com", url("https://github.com/ddworak")), + Developer("ddworak", "Dawid Dworak", "d.dworak@avsystem.com", url("https://github.com/ddworak")) ), ), @@ -91,23 +98,23 @@ lazy val subprojectSettings = Seq( })), libraryDependencies ++= Seq( compilerPlugin("com.avsystem.commons" %% "commons-analyzer" % avsCommonsVersion), - "org.scalatest" %% "scalatest" % scalatestVersion % Test + "org.scalatest" %% "scalatest" % scalatestVersion % Test, ), - Compile / doc / sources := Seq.empty + Compile / doc / sources := Seq.empty, ) -lazy val scex = project.in(file(".")) - .aggregate(`scex-macros`, `scex-core`, `scex-util`, `scex-test`) - .settings(noPublishSettings: _*) +lazy val scex = + project.in(file(".")).aggregate(`scex-macros`, `scex-core`, `scex-util`, `scex-test`).settings(noPublishSettings: _*) lazy val `scex-macros` = project .settings(subprojectSettings: _*) .settings( libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, - libraryDependencies += "com.avsystem.commons" %% "commons-macros" % avsCommonsVersion + libraryDependencies += "com.avsystem.commons" %% "commons-macros" % avsCommonsVersion, ) -lazy val `scex-core` = project.dependsOn(`scex-macros` % CompileAndTest) +lazy val `scex-core` = project + .dependsOn(`scex-macros` % CompileAndTest) .settings(subprojectSettings: _*) .settings( libraryDependencies ++= Seq( @@ -122,7 +129,8 @@ lazy val `scex-core` = project.dependsOn(`scex-macros` % CompileAndTest) ) ) -lazy val `scex-util` = project.dependsOn(`scex-core` % CompileAndTest) +lazy val `scex-util` = project + .dependsOn(`scex-core` % CompileAndTest) .settings(subprojectSettings: _*) .settings( libraryDependencies ++= Seq( @@ -131,6 +139,7 @@ lazy val `scex-util` = project.dependsOn(`scex-core` % CompileAndTest) ) ) -lazy val `scex-test` = project.dependsOn(`scex-core` % CompileAndTest, `scex-util`) +lazy val `scex-test` = project + .dependsOn(`scex-core` % CompileAndTest, `scex-util`) .settings(subprojectSettings: _*) - .settings(noPublishSettings: _*) \ No newline at end of file + .settings(noPublishSettings: _*) diff --git a/project/plugins.sbt b/project/plugins.sbt index a0097dda..dc5b3ce2 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,3 +3,4 @@ logLevel := Level.Warn addSbtPlugin("org.jetbrains.scala" % "sbt-ide-settings" % "1.1.4") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.2") addSbtPlugin("com.github.sbt" % "sbt-github-actions" % "0.30.0") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.6.1") diff --git a/scex-core/src/main/scala/com/avsystem/scex/EvaluationException.scala b/scex-core/src/main/scala/com/avsystem/scex/EvaluationException.scala index 390c42d0..f7f1323a 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/EvaluationException.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/EvaluationException.scala @@ -2,8 +2,6 @@ package com.avsystem.scex import scala.util.control.NoStackTrace -/** - * Created: 16-06-2014 - * Author: ghik +/** Created: 16-06-2014 Author: ghik */ final case class EvaluationException(cause: Throwable) extends RuntimeException(cause) with NoStackTrace diff --git a/scex-core/src/main/scala/com/avsystem/scex/Expression.scala b/scex-core/src/main/scala/com/avsystem/scex/Expression.scala index b387fa3d..4da178f0 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/Expression.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/Expression.scala @@ -19,7 +19,8 @@ abstract class AbstractExpression[-C <: ExpressionContext[_, _], +T] def eval(context: C): T - final def apply(context: C): T = try eval(context) catch { + final def apply(context: C): T = try eval(context) + catch { case NonFatal(cause) => throw new EvaluationException(cause) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/ExpressionContext.scala b/scex-core/src/main/scala/com/avsystem/scex/ExpressionContext.scala index 0ed20ab9..f3911b53 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/ExpressionContext.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/ExpressionContext.scala @@ -4,9 +4,7 @@ import com.avsystem.scex.compiler.annotation.NotValidated import scala.language.higherKinds -/** - * Created: 23-09-2013 - * Author: ghik +/** Created: 23-09-2013 Author: ghik */ trait ExpressionContext[R, V] { type Root = R diff --git a/scex-core/src/main/scala/com/avsystem/scex/ExpressionDebugInfo.scala b/scex-core/src/main/scala/com/avsystem/scex/ExpressionDebugInfo.scala index 47c5d5c5..bcb51097 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/ExpressionDebugInfo.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/ExpressionDebugInfo.scala @@ -2,20 +2,22 @@ package com.avsystem.scex import com.avsystem.scex.compiler.ExpressionDef -/** - * Created: 16-06-2014 - * Author: ghik - */ +/** Created: 16-06-2014 Author: ghik + */ class ExpressionDebugInfo( - val definition: ExpressionDef) { + val definition: ExpressionDef +) { lazy val originalLines = { val mapping = definition.positionMapping.reverse val lineLengths = definition.expression.split('\n').iterator.map(l => l.length + 1) val originalLineStarts = lineLengths.scanLeft(0)(_ + _).map(mapping.apply) - originalLineStarts.sliding(2).map { - case Seq(start, end) => definition.originalExpression.substring(start, end - 1) - }.toVector + originalLineStarts + .sliding(2) + .map { case Seq(start, end) => + definition.originalExpression.substring(start, end - 1) + } + .toVector } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/ExpressionProfile.scala b/scex-core/src/main/scala/com/avsystem/scex/ExpressionProfile.scala index 9199c5ae..9ed32fff 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/ExpressionProfile.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/ExpressionProfile.scala @@ -11,7 +11,8 @@ class ExpressionProfile( val symbolAttributes: SymbolAttributes, val expressionHeader: String, val expressionUtils: NamedSource, - val dynamicVariablesEnabled: Boolean) { + val dynamicVariablesEnabled: Boolean, +) { @bincompat def this( @@ -20,8 +21,16 @@ class ExpressionProfile( symbolValidator: SymbolValidator, symbolAttributes: SymbolAttributes, expressionHeader: String, - expressionUtils: NamedSource - ) = this(name, syntaxValidator, symbolValidator, symbolAttributes, expressionHeader, expressionUtils, dynamicVariablesEnabled = true) + expressionUtils: NamedSource, + ) = this( + name, + syntaxValidator, + symbolValidator, + symbolAttributes, + expressionHeader, + expressionUtils, + dynamicVariablesEnabled = true, + ) override def toString = s"ExpressionProfile[$name]" } diff --git a/scex-core/src/main/scala/com/avsystem/scex/NamedSource.scala b/scex-core/src/main/scala/com/avsystem/scex/NamedSource.scala index 4326f330..f127711b 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/NamedSource.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/NamedSource.scala @@ -1,9 +1,7 @@ package com.avsystem.scex -/** - * Represents named source "file". Used to pass around compilable code fragments in runtime. - * - * Created: 29-10-2014 - * Author: ghik - */ +/** Represents named source "file". Used to pass around compilable code fragments in runtime. + * + * Created: 29-10-2014 Author: ghik + */ final case class NamedSource(name: String, code: String) diff --git a/scex-core/src/main/scala/com/avsystem/scex/Setter.scala b/scex-core/src/main/scala/com/avsystem/scex/Setter.scala index 92276096..b6440658 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/Setter.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/Setter.scala @@ -2,9 +2,7 @@ package com.avsystem.scex import scala.annotation.implicitNotFound -/** - * Created: 28-11-2013 - * Author: ghik +/** Created: 28-11-2013 Author: ghik */ trait Setter[-T] extends (T => Unit) { def acceptedType: Type diff --git a/scex-core/src/main/scala/com/avsystem/scex/Type.scala b/scex-core/src/main/scala/com/avsystem/scex/Type.scala index 2567a1fd..44e10c68 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/Type.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/Type.scala @@ -1,9 +1,7 @@ package com.avsystem.scex -/** - * Author: ghik - * Created: 12/10/14. - */ +/** Author: ghik Created: 12/10/14. + */ final case class Type(fullRepr: String, erasure: Class[_]) { override def toString: String = fullRepr } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/CachingScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/CachingScexCompiler.scala index fd4fde71..46e07bf3 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/CachingScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/CachingScexCompiler.scala @@ -53,7 +53,8 @@ trait CachingScexCompiler extends ScexCompiler { override protected def preprocess(expression: String, template: Boolean) = unwrapExecutionException( - preprocessingCache.get((expression, template), callable(super.preprocess(expression, template)))) + preprocessingCache.get((expression, template), callable(super.preprocess(expression, template))) + ) override protected def compileExpression(exprDef: ExpressionDef) = { val result = unwrapExecutionException(expressionCache.get(exprDef, callable(super.compileExpression(exprDef)))) @@ -63,32 +64,43 @@ trait CachingScexCompiler extends ScexCompiler { } override protected def compileProfileObject(profile: ExpressionProfile) = { - val result = unwrapExecutionException(underLock( - profileCompilationResultsCache.get(profile, callable(super.compileProfileObject(profile))))) + val result = unwrapExecutionException( + underLock(profileCompilationResultsCache.get(profile, callable(super.compileProfileObject(profile)))) + ) invalidateCacheEntry(result, () => profileCompilationResultsCache.invalidate(profile)) result } override protected def compileExpressionUtils(source: NamedSource) = { - val result = unwrapExecutionException(underLock( - utilsCompilationResultsCache.get(source.name, callable(super.compileExpressionUtils(source))))) + val result = unwrapExecutionException( + underLock(utilsCompilationResultsCache.get(source.name, callable(super.compileExpressionUtils(source)))) + ) invalidateCacheEntry(result, () => utilsCompilationResultsCache.invalidate(source.name)) result } - override protected def compileJavaGetterAdapters(profile: ExpressionProfile, name: String, classes: Seq[Class[_]], full: Boolean) = - unwrapExecutionException(underLock( - javaGetterAdaptersCache.get((profile.name, name, classes, full), callable(super.compileJavaGetterAdapters(profile, name, classes, full))))) + override protected def compileJavaGetterAdapters( + profile: ExpressionProfile, + name: String, + classes: Seq[Class[_]], + full: Boolean, + ) = + unwrapExecutionException( + underLock( + javaGetterAdaptersCache.get( + (profile.name, name, classes, full), + callable(super.compileJavaGetterAdapters(profile, name, classes, full)), + ) + ) + ) override def compileSyntaxValidator(source: NamedSource) = - unwrapExecutionException( - syntaxValidatorsCache.get(source.name, callable(super.compileSyntaxValidator(source)))) + unwrapExecutionException(syntaxValidatorsCache.get(source.name, callable(super.compileSyntaxValidator(source)))) override def compileSymbolValidator(source: NamedSource) = - unwrapExecutionException( - symbolValidatorsCache.get(source.name, callable(super.compileSymbolValidator(source)))) + unwrapExecutionException(symbolValidatorsCache.get(source.name, callable(super.compileSymbolValidator(source)))) override def reset(): Unit = underLock { super.reset() @@ -101,7 +113,8 @@ trait CachingScexCompiler extends ScexCompiler { } private def unwrapExecutionException[T](code: => T) = - try code catch { + try code + catch { case e: ExecutionException => throw e.getCause case e: ExecutionError => throw e.getCause } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ClassfileReusingScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ClassfileReusingScexCompiler.scala index a864f4c1..fd115fa2 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ClassfileReusingScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ClassfileReusingScexCompiler.scala @@ -17,26 +17,21 @@ object ClassfileReusingScexCompiler { final val GlobalCacheVersion = 2 } -/** - * An adaptation of ScexCompiler which compiles non-shared classes to disk instead of memory (assuming that classfile +/** An adaptation of ScexCompiler which compiles non-shared classes to disk instead of memory (assuming that classfile * directory is configured). Class files are never being deleted automatically and thus are reused even if the entire * process is restarted. * - * The decision about need for recompilation is made based on signature file generated every time an expression is compiled - * Signature file contains typed and erased (bytecode) signatures of all symbols (methods, fields, etc.) used by - * the expression. In order to reuse previously compiled classfiles, all symbols listed in the signature file must + * The decision about need for recompilation is made based on signature file generated every time an expression is + * compiled Signature file contains typed and erased (bytecode) signatures of all symbols (methods, fields, etc.) used + * by the expression. In order to reuse previously compiled classfiles, all symbols listed in the signature file must * exist and have the same signature they had at the time the expression was originally compiled. * - * This strategy is unfortunately unable to detect some binary compatibility breaches which are source compatible: - * + * This strategy is unfortunately unable to detect some binary compatibility breaches which are source compatible: * - * Created: 21-10-2014 - * Author: ghik + * Created: 21-10-2014 Author: ghik */ trait ClassfileReusingScexCompiler extends ScexCompiler { @@ -114,7 +109,8 @@ trait ClassfileReusingScexCompiler extends ScexCompiler { } ensureDirectoryExists(state.classfileDir.file) val os = state.classfileDir.fileNamed(versionFileName).output - try os.write(currentVersion.getBytes) finally os.close() + try os.write(currentVersion.getBytes) + finally os.close() } super.setup() } @@ -132,14 +128,16 @@ trait ClassfileReusingScexCompiler extends ScexCompiler { nameParts match { case namePart :: rest if owner.isClass || owner.isModule => val ownerType = owner.toType - val members = Iterator(ownerType.member(TypeName(namePart))) ++ symAlternatives(ownerType.member(TermName(namePart))) + val members = Iterator(ownerType.member(TypeName(namePart))) ++ + symAlternatives(ownerType.member(TermName(namePart))) members.filter(_ != NoSymbol).flatMap(symbolsWithName(_, rest)) case Nil => Iterator(owner) case _ => Iterator.empty } symbolsWithName(RootClass, fullName.split("\\.").toList) - .filter(_.isTerm).flatMap(s => s :: s.overrides) + .filter(_.isTerm) + .flatMap(s => s :: s.overrides) .map(s => (typedSignature(global)(s.asTerm), erasedSignature(global)(s.asTerm))) .contains((typedSig, erasedSig)) } @@ -150,7 +148,9 @@ trait ClassfileReusingScexCompiler extends ScexCompiler { outDir <- global.settings.outputDirs.getSingleOutput sigFile <- Option(outDir.lookupName(sigFileName, directory = false)) if isValid(new String(sigFile.toCharArray)) } yield { - logger.debug(s"Expression source file ${sourceFile.file.name} has already been compiled and bytecode is compatible.") + logger.debug( + s"Expression source file ${sourceFile.file.name} has already been compiled and bytecode is compatible." + ) } // If we're about to recompile expression, then we need to make the compiler forget about the old, cached one that @@ -239,9 +239,11 @@ trait ClassfileReusingScexCompiler extends ScexCompiler { } { logger.debug(s"Saving source and signatures file for ${unit.source.file.name}:\n$sig") val sourceWriter = new OutputStreamWriter(outDir.fileNamed(unit.source.file.name + ".scala").output) - try sourceWriter.write(unit.source.content) finally sourceWriter.close() + try sourceWriter.write(unit.source.content) + finally sourceWriter.close() val sigOutputStream = outDir.fileNamed(unit.source.file.name + ".sig").output - try sigOutputStream.write(sig.getBytes) finally sigOutputStream.close() + try sigOutputStream.write(sig.getBytes) + finally sigOutputStream.close() sigs.remove(unit) } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/CodeGeneration.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/CodeGeneration.scala index 5aa1b58c..052f2efd 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/CodeGeneration.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/CodeGeneration.scala @@ -24,7 +24,7 @@ object CodeGeneration { clazz == classOf[Boolean] || clazz == classOf[jl.Boolean] method.getName match { - case name@BeanGetterNamePattern(capitalizedName, _) if name != "getClass" => + case name @ BeanGetterNamePattern(capitalizedName, _) if name != "getClass" => Some((uncapitalize(capitalizedName), false)) case BooleanBeanGetterNamePattern(capitalizedName, _) if isBoolOrBoolean(method.getReturnType) => Some((uncapitalize(capitalizedName), true)) @@ -87,17 +87,16 @@ object CodeGeneration { str.flatMap(escapedChar) object TypedVariables { - /** - * Use this to validate variable names in your code - vars with these characters in names are guaranteed to fail - * due to compilation error. - */ + + /** Use this to validate variable names in your code - vars with these characters in names are guaranteed to fail + * due to compilation error. + */ val IllegalCharsInVarName: Set[Char] = Set('\n', '\r', '`', '\\') } - /** - * Generates code of implicit view for given Java class that adds Scala-style getters - * forwarding to existing Java-style getters of given class. - */ + /** Generates code of implicit view for given Java class that adds Scala-style getters forwarding to existing + * Java-style getters of given class. + */ def generateJavaGetterAdapter(clazz: Class[_], full: Boolean): Option[String] = { // generate scala getters val methods = @@ -105,8 +104,8 @@ object CodeGeneration { else clazz.getMethods.filter(m => m.getDeclaringClass == clazz || isMultipleInherited(clazz, m)) val scalaGetters = methods.collect { - case method@JavaGetter(propName, _) if !method.isSynthetic && - Modifier.isPublic(method.getModifiers) && !Modifier.isStatic(method.getModifiers) => + case method @ JavaGetter(propName, _) + if !method.isSynthetic && Modifier.isPublic(method.getModifiers) && !Modifier.isStatic(method.getModifiers) => s"def `$propName` = _wrapped.${method.getName}\n" } @@ -114,7 +113,8 @@ object CodeGeneration { val classBody = scalaGetters.sorted.mkString val ExistentialType(polyTpe, typeVariables) = classToExistential(clazz) - val generics = if (typeVariables.nonEmpty) typeVariableDeclarations(typeVariables).mkString("[", ", ", "]") else "" + val generics = + if (typeVariables.nonEmpty) typeVariableDeclarations(typeVariables).mkString("[", ", ", "]") else "" val wrappedTpe = javaTypeAsScalaType(polyTpe) val adapterWithGenerics = adapterName(clazz, full) + generics @@ -138,7 +138,8 @@ object CodeGeneration { fullAdapterClassNameOpt: Option[String], profileObjectPkg: Option[String], utilsObjectPkg: Option[String], - noMacroProcessing: Boolean) = { + noMacroProcessing: Boolean, + ) = { val ExpressionDef(profile, template, setter, expression, header, contextType, resultType, variableTypes) = exprDef @@ -157,13 +158,15 @@ object CodeGeneration { "" } - val interpolationPrefix = if (template) if (!noMacroProcessing) InterpolationOpen else NoMacrosInterpolationOpen else "" + val interpolationPrefix = + if (template) if (!noMacroProcessing) InterpolationOpen else NoMacrosInterpolationOpen else "" val interpolationPostfix = if (template) InterpolationClose else "" val setterConversion = if (setter) s"$MacroProcessor.asSetter[$resultType]" else "" - val processingPrefix = if (noMacroProcessing) "" - else - s""" + val processingPrefix = + if (noMacroProcessing) "" + else + s""" | $MacroProcessor.markExpression( | $setterConversion( | $MacroProcessor.validate[$contextType, ${if (setter) "Any" else resultType}]( @@ -172,7 +175,7 @@ object CodeGeneration { val processingPostfix = if (noMacroProcessing) "" else "))))" - val dynamicVariablesDef = { + val dynamicVariablesDef = // skip definition if neither typed variables provided nor dynamic variable accessor enabled if (variableTypes.nonEmpty || profile.dynamicVariablesEnabled) { val dynamicVariableAccessorDef = @@ -184,8 +187,8 @@ object CodeGeneration { val validatePrefix = if (noMacroProcessing) "" else s"$MacroProcessor.validate(" val validatePostfix = if (noMacroProcessing) "" else ")" - val typedVariables = variableTypes.toList.sorted.iterator.map { - case (name, tpe) => + val typedVariables = variableTypes.toList.sorted.iterator + .map { case (name, tpe) => val escapedName = escapeString(name) s""" | private def `${escapedName}VarTag` = ${validatePrefix}inferVarTag[$tpe]$validatePostfix @@ -196,7 +199,8 @@ object CodeGeneration { | @$AnnotationPkg.NotValidated def `${name}_=`(value: $tpe): Unit = | $ContextSymbol.setTypedVariable("$escapedName", value)(`${escapedName}VarTag`) """.stripMargin - }.mkString("\n") + } + .mkString("\n") s""" |class $VariableAccessorClassName extends @@ -208,18 +212,18 @@ object CodeGeneration { s""" | $variableAccessorClassDef - | val $VariablesSymbol = new ${if (variableTypes.nonEmpty) VariableAccessorClassName else dynamicVariableAccessorDef}: @$AnnotationPkg.Input + | val $VariablesSymbol = new ${if (variableTypes.nonEmpty) VariableAccessorClassName + else dynamicVariableAccessorDef}: @$AnnotationPkg.Input |""".stripMargin } else "" - } val profileImport = profileObjectPkg.fold("")(pkg => s"import $pkg.$ProfileObjectName._") val utilsImport = utilsObjectPkg.fold("")(pkg => s"import $pkg.$UtilsObjectName._") - //comment with profile name ensures that caching distinguishes between profiles - //_result is needed because: https://groups.google.com/forum/#!topic/scala-user/BAK-mU7o6nM + // comment with profile name ensures that caching distinguishes between profiles + // _result is needed because: https://groups.google.com/forum/#!topic/scala-user/BAK-mU7o6nM val prefix = - s""" + s""" |// profile: ${profile.name} | |import scala.Predef.{wrapString => _, _} @@ -245,8 +249,7 @@ object CodeGeneration { | { |""".stripMargin + interpolationPrefix - val postfix = interpolationPostfix + - s""" + val postfix = interpolationPostfix + s""" | } | $processingPostfix | _result @@ -265,7 +268,8 @@ object CodeGeneration { val adapterConversions = adapters.iterator.map { case (clazz, adapterName) => val ExistentialType(polyTpe, typeVariables) = classToExistential(clazz) val wrappedTpe = javaTypeAsScalaType(polyTpe) - val generics = if (typeVariables.nonEmpty) typeVariableDeclarations(typeVariables).mkString("[", ", ", "]") else "" + val generics = + if (typeVariables.nonEmpty) typeVariableDeclarations(typeVariables).mkString("[", ", ", "]") else "" val adapterWithGenerics = adapterName + generics s""" @@ -274,23 +278,24 @@ object CodeGeneration { """.stripMargin }.mkString - if (adapterConversions.nonEmpty) Some( - s""" + if (adapterConversions.nonEmpty) + Some( + s""" |object $ProfileObjectName extends $MarkersObj.ProfileObject { |$adapterConversions |} | """.stripMargin - ) else None + ) + else None } - def generateExpressionUtils(code: String) = { + def generateExpressionUtils(code: String) = s""" |object Utils extends $MarkersObj.ExpressionUtil { |$code |} """.stripMargin - } def wrapForParsing(code: String, template: Boolean): (String, Int) = { val prefix = "object o {" + (if (template) InterpolationOpen else "") @@ -298,35 +303,31 @@ object CodeGeneration { (s"$prefix$code$postfix", prefix.length) } - def generateSyntaxValidator(code: String) = { + def generateSyntaxValidator(code: String) = s""" |final class $SyntaxValidatorClassName extends $ScexPkg.validation.SyntaxValidator { |$code |} """.stripMargin - } - def generateSymbolValidator(accessSpecs: String) = { + def generateSymbolValidator(accessSpecs: String) = s""" |final class $SymbolValidatorClassName extends $ScexPkg.validation.SymbolValidator { | val infoList = {$accessSpecs} |} """.stripMargin - } - def generateSymbolAttributes(attributes: String) = { + def generateSymbolAttributes(attributes: String) = s""" |final class $SymbolAttributesClassName extends $ScexPkg.presentation.SymbolAttributes({$attributes}) """.stripMargin - } - def wrapInSource(code: String, pkgName: String): String = { + def wrapInSource(code: String, pkgName: String): String = s""" |package $pkgName | |$code """.stripMargin - } def wrapInSource(code: String, offset: Int, pkgName: String): (String, String, Int) = { val prefix = @@ -346,7 +347,13 @@ object CodeGeneration { s"$templateOptimizingObj.checkConstant($templateOptimizingObj.reifyImplicitView[$resultType](_dummy_literal))\n" } - def implicitLiteralConversionClass(profileObjectPkg: Option[String], utilsObjectPkg: Option[String], profileHeader: String, header: String, resultType: String) = { + def implicitLiteralConversionClass( + profileObjectPkg: Option[String], + utilsObjectPkg: Option[String], + profileHeader: String, + header: String, + resultType: String, + ) = { val templateOptimizingScexCompiler = s"$ScexPkg.compiler.TemplateOptimizingScexCompiler" val profileImport = profileObjectPkg.fold("")(pkg => s"import $pkg.$ProfileObjectName._") val utilsImport = utilsObjectPkg.fold("")(pkg => s"import $pkg.$UtilsObjectName._") diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/DefaultScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/DefaultScexCompiler.scala index 3d25d818..a4102e10 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/DefaultScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/DefaultScexCompiler.scala @@ -3,16 +3,13 @@ package compiler import com.avsystem.scex.compiler.presentation.{CachingScexPresentationCompiler, ScexPresentationCompiler} -/** - * Created: 17-10-2013 - * Author: ghik - */ +/** Created: 17-10-2013 Author: ghik + */ class DefaultScexCompiler(val settings: ScexSettings) extends ScexCompiler - with ScexPresentationCompiler - with ClassfileReusingScexCompiler - with TemplateOptimizingScexCompiler - with CachingScexCompiler - with CachingScexPresentationCompiler - with WeakReferenceWrappingScexCompiler - + with ScexPresentationCompiler + with ClassfileReusingScexCompiler + with TemplateOptimizingScexCompiler + with CachingScexCompiler + with CachingScexPresentationCompiler + with WeakReferenceWrappingScexCompiler diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionDef.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionDef.scala index 92fcf8d0..f2b0cca1 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionDef.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionDef.scala @@ -3,9 +3,7 @@ package compiler import com.avsystem.scex.parsing.PositionMapping -/** - * Created: 14-11-2013 - * Author: ghik +/** Created: 14-11-2013 Author: ghik */ final case class ExpressionDef( profile: ExpressionProfile, diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionMacroProcessor.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionMacroProcessor.scala index fad670a7..f47cabf1 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionMacroProcessor.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionMacroProcessor.scala @@ -8,10 +8,9 @@ import scala.annotation.tailrec import scala.language.experimental.macros import scala.reflect.macros.whitebox -/** - * Object used during expression compilation to validate the expression (syntax, invocations, etc.) - * This must be a Scala object and not a class because it contains macros. Validation is performed against - * given ExpressionProfile which is injected into this object by ScexCompiler by means of a dynamic variable. +/** Object used during expression compilation to validate the expression (syntax, invocations, etc.) This must be a + * Scala object and not a class because it contains macros. Validation is performed against given ExpressionProfile + * which is injected into this object by ScexCompiler by means of a dynamic variable. */ object ExpressionMacroProcessor { def markExpression[T](expr: T): T = macro ExpressionMacroProcessor.markExpression_impl[T] @@ -68,27 +67,28 @@ class ExpressionMacroProcessor(val c: whitebox.Context) extends MacroUtils with expr.tree } - def applyTypesafeEquals_impl[T](expr: c.Expr[T]): c.Tree = { + def applyTypesafeEquals_impl[T](expr: c.Expr[T]): c.Tree = if (c.inferImplicitValue(typeOf[TypesafeEqualsEnabled]) != EmptyTree) { object transformer extends Transformer { override def transform(tree: Tree): Tree = tree match { - case apply@Apply(Select(left, operator), List(right)) => operator.decodedName.toString match { - case "==" => - c.typecheck( - typesafeEquals(transform(left), transform(right), apply.pos), - pt = typeOf[Boolean] - ) - case "!=" => - internal.setPos( + case apply @ Apply(Select(left, operator), List(right)) => + operator.decodedName.toString match { + case "==" => c.typecheck( - q"!${typesafeEquals(transform(left), transform(right), apply.pos)}", - pt = typeOf[Boolean] - ), - apply.pos - ) - case _ => - super.transform(tree) - } + typesafeEquals(transform(left), transform(right), apply.pos), + pt = typeOf[Boolean], + ) + case "!=" => + internal.setPos( + c.typecheck( + q"!${typesafeEquals(transform(left), transform(right), apply.pos)}", + pt = typeOf[Boolean], + ), + apply.pos, + ) + case _ => + super.transform(tree) + } case _ => super.transform(tree) } @@ -98,8 +98,6 @@ class ExpressionMacroProcessor(val c: whitebox.Context) extends MacroUtils with } else expr.tree - } - def typesafeEquals(leftTree: Tree, rightTree: Tree, pos: Position): Tree = { val leftTpe = leftTree.tpe.widen val rightTpe = rightTree.tpe.widen @@ -107,16 +105,17 @@ class ExpressionMacroProcessor(val c: whitebox.Context) extends MacroUtils with lazy val leftToRightConv = c.inferImplicitView(leftTree, leftTree.tpe, rightTree.tpe.widen) lazy val rightToLeftConv = c.inferImplicitView(rightTree, rightTree.tpe, leftTree.tpe.widen) - val result = if (leftTpe <:< rightTpe) - q"$leftTree == $rightTree" - else if (rightTpe <:< leftTpe) - q"$rightTree == $leftTree" - else if (rightToLeftConv != EmptyTree) - q"$leftTree == $rightToLeftConv($rightTree)" - else if (leftToRightConv != EmptyTree) - q"$leftToRightConv($leftTree) == $rightTree" - else - c.abort(pos, s"Values of types ${leftTpe.dealias} and ${rightTpe.dealias} cannot be compared for equality") + val result = + if (leftTpe <:< rightTpe) + q"$leftTree == $rightTree" + else if (rightTpe <:< leftTpe) + q"$rightTree == $leftTree" + else if (rightToLeftConv != EmptyTree) + q"$leftTree == $rightToLeftConv($rightTree)" + else if (leftToRightConv != EmptyTree) + q"$leftToRightConv($leftTree) == $rightTree" + else + c.abort(pos, s"Values of types ${leftTpe.dealias} and ${rightTpe.dealias} cannot be compared for equality") internal.setPos(result, pos) } @@ -132,23 +131,26 @@ class ExpressionMacroProcessor(val c: whitebox.Context) extends MacroUtils with q"(value: $ttpe) => ${bodyGen(q"value")}" def translate(tree: Tree): Tree = tree match { - case Apply(fun, List(arg)) if fun.symbol == safeToString || (fun.symbol :: fun.symbol.overrides).contains(splicerToString) => + case Apply(fun, List(arg)) + if fun.symbol == safeToString || (fun.symbol :: fun.symbol.overrides).contains(splicerToString) => translate(arg) - case Select(prefix@Ident(_), TermName(propertyName)) if isRootAdapter(prefix.tpe) => + case Select(prefix @ Ident(_), TermName(propertyName)) if isRootAdapter(prefix.tpe) => reifySetterFunction(Select(Ident(TermName(CodeGeneration.RootSymbol)), TermName("set" + propertyName.capitalize))) case Select(ImplicitlyConverted(prefix, fun), TermName(propertyName)) if isAdapterConversion(fun.symbol) => reifySetterFunction(Select(prefix, TermName("set" + propertyName.capitalize))) - case Select(va@Ident(TermName(CodeGeneration.VariablesSymbol)), TermName(varName)) if va.tpe <:< dynamicVarAccessorTpe => + case Select(va @ Ident(TermName(CodeGeneration.VariablesSymbol)), TermName(varName)) + if va.tpe <:< dynamicVarAccessorTpe => val ctx = Ident(TermName(CodeGeneration.ContextSymbol)) reifyFunction(arg => q"$ctx.setTypedVariable[${tree.tpe}]($varName, $arg)") case Select(prefix, TermName(getterName)) if tree.symbol.isMethod => val returnType = tree.symbol.asMethod.returnType val setterName = getterName match { - case BooleanBeanGetterNamePattern(capitalizedProperty, _) if returnType <:< booleanTpe || returnType <:< jBooleanTpe => + case BooleanBeanGetterNamePattern(capitalizedProperty, _) + if returnType <:< booleanTpe || returnType <:< jBooleanTpe => "set" + capitalizedProperty case BeanGetterNamePattern(capitalizedProperty, _) => "set" + capitalizedProperty @@ -167,8 +169,7 @@ class ExpressionMacroProcessor(val c: whitebox.Context) extends MacroUtils with case Apply(Select(prefix, TermName("apply")), List(soleArgument)) => reifyFunction(arg => q"$prefix.update($soleArgument, $convertOnSet($arg))") - case Apply(Select(prefix, TermName("selectDynamic")), List(dynamicNameArg)) - if prefix.tpe <:< typeOf[Dynamic] => + case Apply(Select(prefix, TermName("selectDynamic")), List(dynamicNameArg)) if prefix.tpe <:< typeOf[Dynamic] => reifySetterFunction(q"$prefix.updateDynamic($convertOnSet($dynamicNameArg))") diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionSourceFile.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionSourceFile.scala index 0a1d019d..ead749fb 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionSourceFile.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionSourceFile.scala @@ -3,15 +3,14 @@ package compiler import scala.reflect.internal.util.Position -/** - * Created: 13-12-2013 - * Author: ghik - */ +/** Created: 13-12-2013 Author: ghik + */ class ExpressionSourceFile( val exprDef: ExpressionDef, sourceName: String, val code: String, - startOffset: Int) extends ScexSourceFile(sourceName, code, shared = false) { + startOffset: Int, +) extends ScexSourceFile(sourceName, code, shared = false) { require(exprDef != null, "Expression definition cannot be null") diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionTreeAttachment.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionTreeAttachment.scala index 939d489c..b8c281a3 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionTreeAttachment.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ExpressionTreeAttachment.scala @@ -1,7 +1,5 @@ package com.avsystem.scex.compiler -/** - * Created: 04-11-2014 - * Author: ghik - */ +/** Created: 04-11-2014 Author: ghik + */ object ExpressionTreeAttachment diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/JavaTypeParsing.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/JavaTypeParsing.scala index 8e3a07df..7f80c9f1 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/JavaTypeParsing.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/JavaTypeParsing.scala @@ -9,9 +9,8 @@ import scala.Array import scala.collection.mutable.ListBuffer import scala.language.existentials -/** - * Utils for conversions of Java types into string representations of their Scala counterparts. - */ +/** Utils for conversions of Java types into string representations of their Scala counterparts. + */ object JavaTypeParsing { final case class ScalaTypeVariable(name: String, upperBounds: Array[Type], lowerBounds: Array[Type]) extends Type @@ -77,7 +76,7 @@ object JavaTypeParsing { classOf[Int] -> "Int", classOf[Long] -> "Long", classOf[Float] -> "Float", - classOf[Double] -> "Double" + classOf[Double] -> "Double", ) def javaTypeAsScalaType(tpe: Type): String = tpe match { @@ -107,7 +106,8 @@ object JavaTypeParsing { case WrappedParameterizedType(rawType, ownerType, typeArguments) => val clazz = rawType.asInstanceOf[Class[_]] - val typeArgumentsRepr = if (typeArguments.nonEmpty) typeArguments.map(javaTypeAsScalaType).mkString("[", ", ", "]") else "" + val typeArgumentsRepr = + if (typeArguments.nonEmpty) typeArguments.map(javaTypeAsScalaType).mkString("[", ", ", "]") else "" if (ownerType != null) { javaTypeAsScalaType(ownerType) + "#" + clazz.getSimpleName + typeArgumentsRepr @@ -158,12 +158,11 @@ object JavaTypeParsing { throw new IllegalArgumentException(s"Type $tpe does not have erasure") } - /** - * Example: transforms java type A.D into Scala type - * A[T1,C]#D[T2] forSome {type T1 <: B; type T2 >: E} - * @param paramType - * @return - */ + /** Example: transforms java type A.D into Scala type A[T1,C]#D[T2] forSome + * {type T1 <: B; type T2 >: E} + * @param paramType + * @return + */ def parameterizedTypeToExistential(paramType: ParameterizedType): ExistentialType = { var i = 0 def newTypeVarName() = { @@ -229,9 +228,8 @@ object JavaTypeParsing { } def typeVariableDeclarations(typeVars: List[Type]): List[String] = - typeVars.map { - case TypeVariable(name, upperBounds, lowerBounds) => - name + bounds(upperBounds, lowerBounds) + typeVars.map { case TypeVariable(name, upperBounds, lowerBounds) => + name + bounds(upperBounds, lowerBounds) } val StringSupertypes = Set("String", "Object", "Comparable[String]") ++ Set( @@ -241,7 +239,7 @@ object JavaTypeParsing { classOf[java.io.Serializable], classOf[CharSequence], WrappedParameterizedType(classOf[Comparable[_]], null, Array(classOf[String])), - classOf[String] + classOf[String], ).map(javaTypeAsScalaType) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/Markers.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/Markers.scala index d4c9124d..831ea3e2 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/Markers.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/Markers.scala @@ -1,10 +1,8 @@ package com.avsystem.scex package compiler -/** - * Created: 12-12-2013 - * Author: ghik - */ +/** Created: 12-12-2013 Author: ghik + */ object Markers { trait Synthetic extends Any diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexCompiler.scala index b43d0da7..31f781b9 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexCompiler.scala @@ -47,13 +47,9 @@ trait ScexCompiler extends LoggingUtils { def mapPosition(pos: Position, mapping: PositionMapping): Position = if (pos.isRange) { - val result = pos - .withStart(mapping(pos.start)) - .withPoint(mapping(pos.point)) - .withEnd(mapping(pos.end)) + val result = pos.withStart(mapping(pos.start)).withPoint(mapping(pos.point)).withEnd(mapping(pos.end)) if (pos.isTransparent) result.makeTransparent else result - } - else if (pos.isOffset) + } else if (pos.isOffset) pos.withPoint(mapping(pos.point)) else pos @@ -98,10 +94,9 @@ trait ScexCompiler extends LoggingUtils { private var global: ScexGlobal = _ private var reporter: Reporter = _ - /** - * Classloader for stuff that will be never reclaimed after compilation - - * profiles, validators, custom util classes, etc. - */ + /** Classloader for stuff that will be never reclaimed after compilation - profiles, validators, custom util classes, + * etc. + */ private var sharedClassLoader: ScexClassLoader = _ private var compilationCount: Int = _ @@ -136,24 +131,29 @@ trait ScexCompiler extends LoggingUtils { protected def instantiate[T](classLoader: ClassLoader, className: String): T = Class.forName(className, true, classLoader).getConstructor().newInstance().asInstanceOf[T] - protected def compileJavaGetterAdapters(profile: ExpressionProfile, name: String, classes: Seq[Class[_]], full: Boolean): Try[Seq[Option[String]]] = + protected def compileJavaGetterAdapters( + profile: ExpressionProfile, + name: String, + classes: Seq[Class[_]], + full: Boolean, + ): Try[Seq[Option[String]]] = if (settings.noGetterAdapters.value) Success(classes.map(_ => None)) else { val (fullCode, names) = classes.foldLeft(("", Vector.empty[Option[String]])) { - case ((prevCode, prevNames), clazz) => generateJavaGetterAdapter(clazz, full) match { - case Some(code) => (prevCode + "\n" + code, prevNames :+ Some(adapterName(clazz, full))) - case None => (prevCode, prevNames :+ None) - } + case ((prevCode, prevNames), clazz) => + generateJavaGetterAdapter(clazz, full) match { + case Some(code) => (prevCode + "\n" + code, prevNames :+ Some(adapterName(clazz, full))) + case None => (prevCode, prevNames :+ None) + } } val codeToCompile = wrapInSource(fullCode, AdaptersPkgPrefix + NameTransformer.encode(profile.name)) val sourceFile = new ScexSourceFile(name + profile.name, codeToCompile, shared = true) - def result() = { + def result() = compile(sourceFile) match { case Left(_) => names case Right(errors) => throw CompilationFailedException(codeToCompile, errors) } - } Try(result()) } @@ -161,8 +161,8 @@ trait ScexCompiler extends LoggingUtils { protected def compileProfileObject(profile: ExpressionProfile): Try[Option[String]] = underLock { val classes = profile.symbolValidator.referencedJavaClasses.toVector.sortBy(_.getName) val adapterNames = compileJavaGetterAdapters(profile, "Adapters_", classes, full = false).get - val adapters = (classes zip adapterNames).collect { - case (clazz, Some(adapterName)) => (clazz, adapterName) + val adapters = (classes zip adapterNames).collect { case (clazz, Some(adapterName)) => + (clazz, adapterName) } generateProfileObject(profile, adapters) match { @@ -185,29 +185,33 @@ trait ScexCompiler extends LoggingUtils { } protected def compileExpressionUtils(utils: NamedSource): Try[Option[String]] = - if (utils.code.isEmpty) Success(None) else underLock { - val pkgName = UtilsPkgPrefix + NameTransformer.encode(utils.name) - val codeToCompile = wrapInSource(generateExpressionUtils(utils.code), pkgName) - val sourceFile = new ScexSourceFile(pkgName, codeToCompile, shared = true) + if (utils.code.isEmpty) Success(None) + else + underLock { + val pkgName = UtilsPkgPrefix + NameTransformer.encode(utils.name) + val codeToCompile = wrapInSource(generateExpressionUtils(utils.code), pkgName) + val sourceFile = new ScexSourceFile(pkgName, codeToCompile, shared = true) - def result = - compile(sourceFile) match { - case Left(_) => pkgName - case Right(errors) => throw CompilationFailedException(codeToCompile, errors) - } + def result = + compile(sourceFile) match { + case Left(_) => pkgName + case Right(errors) => throw CompilationFailedException(codeToCompile, errors) + } - Try(Some(result)) - } + Try(Some(result)) + } - protected final def expressionCode(exprDef: ExpressionDef, noMacroProcessing: Boolean = false): (String, String, Int) = { + protected final def expressionCode(exprDef: ExpressionDef, noMacroProcessing: Boolean = false) + : (String, String, Int) = { val profile = exprDef.profile val rootObjectClass = exprDef.rootObjectClass val fullAdapterClassNameOpt = if (profile.symbolValidator.referencedJavaClasses.contains(rootObjectClass)) { val name = adapterName(rootObjectClass, full = true) - compileJavaGetterAdapters(profile, name, Seq(rootObjectClass), full = true) - .get.head.map(name => s"$AdaptersPkgPrefix${NameTransformer.encode(profile.name)}.$name") + compileJavaGetterAdapters(profile, name, Seq(rootObjectClass), full = true).get.head.map(name => + s"$AdaptersPkgPrefix${NameTransformer.encode(profile.name)}.$name" + ) } else None val profileObjectPkg = compileProfileObject(profile).get @@ -222,9 +226,11 @@ trait ScexCompiler extends LoggingUtils { protected final def withGlobal[T](code: ScexGlobal => T): T = underLock { reporter.reset() val global = this.global - val result = try code(global) finally { - reporter.reset() - } + val result = + try code(global) + finally { + reporter.reset() + } result } @@ -283,8 +289,14 @@ trait ScexCompiler extends LoggingUtils { val (pkgName, codeToCompile, offset) = expressionCode(exprDef) // every single expression has its own classloader and virtual directory val sourceFile = new ExpressionSourceFile(exprDef, pkgName, codeToCompile, offset) - val sourceInfo = new SourceInfo(pkgName, codeToCompile, offset, offset + exprDef.expression.length, - sourceFile.offsetToLine(offset) + 1, sourceFile.offsetToLine(offset + exprDef.expression.length - 1) + 2) + val sourceInfo = new SourceInfo( + pkgName, + codeToCompile, + offset, + offset + exprDef.expression.length, + sourceFile.offsetToLine(offset) + 1, + sourceFile.offsetToLine(offset + exprDef.expression.length - 1) + 2, + ) val debugInfo = new ExpressionDebugInfo(exprDef) compile(sourceFile) match { @@ -292,7 +304,8 @@ trait ScexCompiler extends LoggingUtils { val clazz = Class.forName(s"$pkgName.$ExpressionClassName", true, classLoader) clazz.getDeclaredClasses // force loading of inner classes - val expr = clazz.getConstructor(classOf[ExpressionDebugInfo], classOf[SourceInfo]) + val expr = clazz + .getConstructor(classOf[ExpressionDebugInfo], classOf[SourceInfo]) .newInstance(debugInfo, sourceInfo) .asInstanceOf[RawExpression] Success(expr) @@ -310,20 +323,30 @@ trait ScexCompiler extends LoggingUtils { expression: String, variableTypes: Map[String, TypeString[_]] = Map.empty, template: Boolean = true, - header: String = "" + header: String = "", )(implicit cti: ContextTypeInfo[C], - tts: TypeString[T] + tts: TypeString[T], ): Expression[C, T] = { require(profile != null, "Profile cannot be null") require(expression != null, "Expression cannot be null") require(header != null, "Header cannot be null") - val strVariableTypes = variableTypes.iterator.map({ case (k, v) => (k, v.value) }).toMap + val strVariableTypes = variableTypes.iterator.map { case (k, v) => (k, v.value) }.toMap val (actualExpression, positionMapping) = preprocess(expression, template) - getCompiledExpression(ExpressionDef(profile, template, setter = false, actualExpression, - header, cti.fullTypeString, tts.value, strVariableTypes)(expression, positionMapping, cti.rootObjectClass)) + getCompiledExpression( + ExpressionDef( + profile, + template, + setter = false, + actualExpression, + header, + cti.fullTypeString, + tts.value, + strVariableTypes, + )(expression, positionMapping, cti.rootObjectClass) + ) } def getCompiledSetterExpression[C <: ExpressionContext[_, _], T]( @@ -331,21 +354,31 @@ trait ScexCompiler extends LoggingUtils { expression: String, template: Boolean = true, variableTypes: Map[String, TypeString[_]] = Map.empty, - header: String = "" + header: String = "", )(implicit cti: ContextTypeInfo[C], - tts: TypeString[T] + tts: TypeString[T], ): Expression[C, Setter[T]] = { require(profile != null, "Profile cannot be null") require(expression != null, "Expression cannot be null") require(header != null, "Header cannot be null") - val strVariableTypes = variableTypes.iterator.map({ case (k, v) => (k, v.value) }).toMap + val strVariableTypes = variableTypes.iterator.map { case (k, v) => (k, v.value) }.toMap val (actualExpression, positionMapping) = preprocess(expression, template) - getCompiledExpression(ExpressionDef(profile, template, setter = true, actualExpression, - header, cti.fullTypeString, tts.value, strVariableTypes)(expression, positionMapping, cti.rootObjectClass)) + getCompiledExpression( + ExpressionDef( + profile, + template, + setter = true, + actualExpression, + header, + cti.fullTypeString, + tts.value, + strVariableTypes, + )(expression, positionMapping, cti.rootObjectClass) + ) } @throws[CompilationFailedException] @@ -376,10 +409,9 @@ trait ScexCompiler extends LoggingUtils { } } - /** - * Compiles arbitrary Scala source file into a dedicated class loader and loads class with given fully qualified name - * from that class loader. - */ + /** Compiles arbitrary Scala source file into a dedicated class loader and loads class with given fully qualified name + * from that class loader. + */ def compileClass(code: String, name: String): Class[_] = underLock { val sourceName = ArbitraryClassSourceNamePrefix + DigestUtils.md5Hex(code) val sourceFile = new ScexSourceFile(sourceName, code, shared = false) @@ -392,10 +424,9 @@ trait ScexCompiler extends LoggingUtils { } } - /** - * Resets internal compiler state by creating completely new instance of Scala compiler and invalidating all - * internal caches. - */ + /** Resets internal compiler state by creating completely new instance of Scala compiler and invalidating all internal + * caches. + */ def reset(): Unit = underLock(setup()) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexGlobal.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexGlobal.scala index 2de63527..51de64fd 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexGlobal.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexGlobal.scala @@ -9,9 +9,7 @@ import scala.reflect.io.AbstractFile import scala.tools.nsc.Global import scala.tools.nsc.plugins.Plugin -/** - * Created: 01-04-2014 - * Author: ghik +/** Created: 01-04-2014 Author: ghik */ trait ScexGlobal extends Global with MacroUtils with SymbolErasures { lazy val universe: this.type = this @@ -22,12 +20,14 @@ trait ScexGlobal extends Global with MacroUtils with SymbolErasures { val (wrappedCode, offset) = CodeGeneration.wrapForParsing(code, template) val sourceFile = new BatchSourceFile("(for_parsing)", wrappedCode) val unit = new CompilationUnit(sourceFile) - val PackageDef(_, List(ModuleDef(_, _, Template(_, _, List(_, expressionTree))))) = new syntaxAnalyzer.UnitParser(unit).parse() + val PackageDef(_, List(ModuleDef(_, _, Template(_, _, List(_, expressionTree))))) = + new syntaxAnalyzer.UnitParser(unit).parse() moveTree(expressionTree, -offset) } def movePosition(pos: Position, offset: Int): Position = pos match { - case tp: TransparentPosition => new TransparentPosition(tp.source, tp.start + offset, tp.point + offset, tp.end + offset) + case tp: TransparentPosition => + new TransparentPosition(tp.source, tp.start + offset, tp.point + offset, tp.end + offset) case rp: RangePosition => new RangePosition(rp.source, rp.start + offset, rp.point + offset, rp.end + offset) case op: OffsetPosition => new OffsetPosition(op.source, op.point + offset) case _ => pos @@ -40,8 +40,7 @@ trait ScexGlobal extends Global with MacroUtils with SymbolErasures { tree } - /** - * Locator with slightly modified inclusion check. + /** Locator with slightly modified inclusion check. */ class ScexLocator(pos: Position) extends Traverser { var last: Tree = _ @@ -60,16 +59,17 @@ trait ScexGlobal extends Global with MacroUtils with SymbolErasures { if (includes(t.pos, pos)) { if (!t.pos.isTransparent) last = t super.traverse(t) - } else t match { - case mdef: MemberDef => - traverseTrees(mdef.mods.annotations) - case _ => - } + } else + t match { + case mdef: MemberDef => + traverseTrees(mdef.mods.annotations) + case _ => + } } } private def includes(pos1: Position, pos2: Position): Boolean = - (pos1 includes pos2) && pos1.end > pos2.start + (pos1.includes(pos2)) && pos1.end > pos2.start } override protected def loadRoughPluginsList(): List[Plugin] = @@ -87,8 +87,8 @@ trait ScexGlobal extends Global with MacroUtils with SymbolErasures { def forgetSymbolsFromSource(file: AbstractFile): Unit = { val symbols = toplevelSymbolsMap.get(file).map(_.toSet).getOrElse(Set.empty) symbols.foreach { s => - //like in: scala.tools.nsc.interactive.Global.filesDeleted - s.owner.info.decls unlink s + // like in: scala.tools.nsc.interactive.Global.filesDeleted + s.owner.info.decls.unlink(s) } toplevelSymbolsMap.remove(file) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSettings.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSettings.scala index c5e5d642..9d215c59 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSettings.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSettings.scala @@ -5,10 +5,8 @@ import java.io.File import scala.reflect.io.{Directory, PlainDirectory} import scala.tools.nsc.Settings -/** - * Created: 21-10-2014 - * Author: ghik - */ +/** Created: 21-10-2014 Author: ghik + */ class ScexSettings extends Settings { classpath.value = System.getProperty("java.class.path") @@ -21,43 +19,64 @@ class ScexSettings extends Settings { private val Positive = Some((1, Int.MaxValue)) - final val expressionExpirationTime = IntSetting("-SCEXexpression-expiration-time", - "Expiration time for expression cache, in seconds", 3600, Positive, _ => None) - - final val expressionCacheSize = IntSetting("-SCEXexpression-cache-size", - "Maximum size of expression cache", 5000, Positive, _ => None) - - final val completionExpirationTime = IntSetting("-SCEXerrors-expiration-time", - "Expiration time for completion caches, in seconds", 600, Positive, _ => None) - - final val errorsCacheSize = IntSetting("-SCEXerrors-cache-size", - "Maximum size of errors cache", 10000, Positive, _ => None) - - final val scopeCompletionCacheSize = IntSetting("-SCEXscope-completion-cache-size", - "Maximum size of scope completion cache", 3000, Positive, _ => None) - - final val typeMembersCacheSize = IntSetting("-SCEXtype-members-cache-size", - "Maximum size of type members cache", 10000, Positive, _ => None) - - final val resetAfterCount = IntSetting("-SCEXreset-after-count", - "Number of compilations after which the compiler will be reset", 2000, Positive, _ => None) - - final val classfileDirectory = StringSetting("-SCEXclassfile-directory", "directory", - "Directory for classfile cache", "") - - final val noPresentation = BooleanSetting("-SCEXno-presentation", - "Turns of the 'presentation' part of the compiler") - - final val noGetterAdapters = BooleanSetting("-SCEXno-getter-adapters", - "Disables generation of Java getter adapter methods") - - final val backwardsCompatCacheVersion = StringSetting("-SCEXbackwards-compat-cache-version", "versionString", - "Additional version string for controlling invalidation of classfile cache", "0") - - final val cacheUnexpectedCompilationExceptions = BooleanSetting("-SCEXcache-unexpected-compilation-exceptions", + final val expressionExpirationTime = IntSetting( + "-SCEXexpression-expiration-time", + "Expiration time for expression cache, in seconds", + 3600, + Positive, + _ => None, + ) + + final val expressionCacheSize = + IntSetting("-SCEXexpression-cache-size", "Maximum size of expression cache", 5000, Positive, _ => None) + + final val completionExpirationTime = IntSetting( + "-SCEXerrors-expiration-time", + "Expiration time for completion caches, in seconds", + 600, + Positive, + _ => None, + ) + + final val errorsCacheSize = + IntSetting("-SCEXerrors-cache-size", "Maximum size of errors cache", 10000, Positive, _ => None) + + final val scopeCompletionCacheSize = + IntSetting("-SCEXscope-completion-cache-size", "Maximum size of scope completion cache", 3000, Positive, _ => None) + + final val typeMembersCacheSize = + IntSetting("-SCEXtype-members-cache-size", "Maximum size of type members cache", 10000, Positive, _ => None) + + final val resetAfterCount = IntSetting( + "-SCEXreset-after-count", + "Number of compilations after which the compiler will be reset", + 2000, + Positive, + _ => None, + ) + + final val classfileDirectory = + StringSetting("-SCEXclassfile-directory", "directory", "Directory for classfile cache", "") + + final val noPresentation = BooleanSetting("-SCEXno-presentation", "Turns of the 'presentation' part of the compiler") + + final val noGetterAdapters = + BooleanSetting("-SCEXno-getter-adapters", "Disables generation of Java getter adapter methods") + + final val backwardsCompatCacheVersion = StringSetting( + "-SCEXbackwards-compat-cache-version", + "versionString", + "Additional version string for controlling invalidation of classfile cache", + "0", + ) + + final val cacheUnexpectedCompilationExceptions = BooleanSetting( + "-SCEXcache-unexpected-compilation-exceptions", "Enables the caching of unexpected exceptions (such as NPE when accessing scex_classes) thrown during the expression compilation. " + - "CompilationFailedExceptions are always cached, regardless of this setting. They indicate e.g. syntax errors, which should always be cached to avoid redundant compilations.", default = false) + "CompilationFailedExceptions are always cached, regardless of this setting. They indicate e.g. syntax errors, which should always be cached to avoid redundant compilations.", + default = false, + ) - def resolvedClassfileDir: Option[PlainDirectory] = Option(classfileDirectory.value) - .filter(_.trim.nonEmpty).map(path => new PlainDirectory(new Directory(new File(path)))) + def resolvedClassfileDir: Option[PlainDirectory] = + Option(classfileDirectory.value).filter(_.trim.nonEmpty).map(path => new PlainDirectory(new Directory(new File(path)))) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSourceFile.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSourceFile.scala index cfcaf490..1d369c70 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSourceFile.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/ScexSourceFile.scala @@ -2,12 +2,9 @@ package com.avsystem.scex.compiler import scala.reflect.internal.util.BatchSourceFile -/** - * Created: 28-10-2014 - * Author: ghik - */ -class ScexSourceFile(name: String, contents: String, val shared: Boolean) - extends BatchSourceFile(name, contents) { +/** Created: 28-10-2014 Author: ghik + */ +class ScexSourceFile(name: String, contents: String, val shared: Boolean) extends BatchSourceFile(name, contents) { override def equals(that: Any): Boolean = that match { case that: ScexSourceFile => file.path == that.file.path && start == that.start diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/SourceInfo.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/SourceInfo.scala index 25e18bea..140b5941 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/SourceInfo.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/SourceInfo.scala @@ -1,13 +1,12 @@ package com.avsystem.scex.compiler -/** - * Created: 03-11-2014 - * Author: ghik - */ +/** Created: 03-11-2014 Author: ghik + */ class SourceInfo( val sourceName: String, val fullCode: String, val startOffset: Int, val endOffset: Int, val firstLine: Int, - val lastLine: Int) \ No newline at end of file + val lastLine: Int, +) diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/SymbolErasures.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/SymbolErasures.scala index ec264019..b0bbbd29 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/SymbolErasures.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/SymbolErasures.scala @@ -7,13 +7,11 @@ import java.{lang => jl} import scala.io.Codec import scala.tools.nsc.Global -/** - * Stuff to translate Symbols into their corresponding Java reflection artifacts. Code copied from - * scala.reflect.runtime.JavaMirrors - * - * Created: 27-10-2014 - * Author: ghik - */ +/** Stuff to translate Symbols into their corresponding Java reflection artifacts. Code copied from + * scala.reflect.runtime.JavaMirrors + * + * Created: 27-10-2014 Author: ghik + */ trait SymbolErasures { this: Global => def classLoader: ClassLoader @@ -22,38 +20,37 @@ trait SymbolErasures { this: Global => private val PackageAndClassPattern = """(.*\.)(.*)$""".r - private def jArrayClass(elemClazz: Class[_]): Class[_] = { + private def jArrayClass(elemClazz: Class[_]): Class[_] = jl.reflect.Array.newInstance(elemClazz, 0).getClass - } - def erasureClass(tpe: Type) = try typeToJavaClass(tpe.erasure) catch { + def erasureClass(tpe: Type) = try typeToJavaClass(tpe.erasure) + catch { case _: ClassNotFoundException | _: NoClassDefFoundError => null } - /** The Java class that corresponds to given Scala type. - * Pre: Scala type is already transformed to Java level. - */ + /** The Java class that corresponds to given Scala type. Pre: Scala type is already transformed to Java level. + */ def typeToJavaClass(tpe: Type): Class[_] = tpe match { case ExistentialType(_, rtpe) => typeToJavaClass(rtpe) case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe)) case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClass) - case tpe@TypeRef(_, sym: AliasTypeSymbol, _) => typeToJavaClass(tpe.dealias) + case tpe @ TypeRef(_, sym: AliasTypeSymbol, _) => typeToJavaClass(tpe.dealias) case SingleType(_, sym: ModuleSymbol) => classToJava(sym.moduleClass.asClass) case _ => throw new NoClassDefFoundError("no Java class corresponding to " + tpe + " found") } - /** The Java class corresponding to given Scala class. - * Note: This only works for - * - top-level classes - * - Scala classes that were generated via jclassToScala - * - classes that have a class owner that has a corresponding Java class - * - * @throws A `ClassNotFoundException` for all Scala classes not in one of these categories. - */ + /** The Java class corresponding to given Scala class. Note: This only works for + * - top-level classes + * - Scala classes that were generated via jclassToScala + * - classes that have a class owner that has a corresponding Java class + * + * @throws A + * `ClassNotFoundException` for all Scala classes not in one of these categories. + */ @throws(classOf[ClassNotFoundException]) private def classToJava(clazz: ClassSymbol): Class[_] = { def noClass = throw new ClassNotFoundException("no Java class corresponding to " + clazz + " found") - //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug + // println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug if (clazz.isPrimitiveValueClass) valueClassToJavaType(clazz) else if (clazz == ArrayClass) @@ -67,7 +64,8 @@ trait SymbolErasures { this: Global => // suggested in https://issues.scala-lang.org/browse/SI-4023?focusedCommentId=54759#comment-54759 var ownerClazz = classToJava(clazz.owner.asClass) - if (childOfTopLevelObject) ownerClazz = Class.forName(ownerClazz.getName stripSuffix "$", true, ownerClazz.getClassLoader) + if (childOfTopLevelObject) + ownerClazz = Class.forName(ownerClazz.getName.stripSuffix("$"), true, ownerClazz.getClassLoader) val ownerChildren = ownerClazz.getDeclaredClasses var fullNameOfJavaClass = ownerClazz.getName @@ -97,40 +95,35 @@ trait SymbolErasures { this: Global => private final object compactifier extends (String => String) { val md5 = MessageDigest.getInstance("MD5") - /** - * COMPACTIFY - * - * The maximum length of a filename on some platforms is 240 chars (docker). - * Therefore, compactify names that would create a filename longer than that. - * A compactified name looks like - * prefix + $$$$ + md5 + $$$$ + suffix, - * where the prefix and suffix are the first and last quarter of the name, - * respectively. - * - * So how long is too long? For a (flattened class) name, the resulting file - * will be called "name.class", or, if it's a module class, "name$.class" - * (see scala/bug#8199). Therefore the maximum suffix is 7 characters, and - * names that are over (240 - 7) characters get compactified. - */ + /** COMPACTIFY + * + * The maximum length of a filename on some platforms is 240 chars (docker). Therefore, compactify names that would + * create a filename longer than that. A compactified name looks like prefix + $$$$ + md5 + $$$$ + suffix, where + * the prefix and suffix are the first and last quarter of the name, respectively. + * + * So how long is too long? For a (flattened class) name, the resulting file will be called "name.class", or, if + * it's a module class, "name$.class" (see scala/bug#8199). Therefore the maximum suffix is 7 characters, and names + * that are over (240 - 7) characters get compactified. + */ final val marker = "$$$$" final val MaxSuffixLength = 7 // "$.class".length + 1 // potential module class suffix and file extension final val MaxNameLength = 240 - MaxSuffixLength def toMD5(s: String, edge: Int): String = { - val prefix = s take edge - val suffix = s takeRight edge + val prefix = s.take(edge) + val suffix = s.takeRight(edge) val cs = s.toArray val bytes = Codec.toUTF8(java.nio.CharBuffer.wrap(cs, 0, cs.length)) - md5 update bytes - val md5chars = (md5.digest() map (b => (b & 0xFF).toHexString)).mkString + md5.update(bytes) + val md5chars = (md5.digest() map (b => (b & 0xff).toHexString)).mkString prefix + marker + md5chars + marker + suffix } def apply(s: String): String = ( if (s.length <= MaxNameLength) s else toMD5(s, MaxNameLength / 4) - ) + ) } private def expandedName(sym: Symbol): String = @@ -138,22 +131,24 @@ trait SymbolErasures { this: Global => else sym.name.toString /** The Java field corresponding to a given Scala field. - * - * @param fld The Scala field. - */ + * + * @param fld + * The Scala field. + */ def fieldToJava(fld: TermSymbol): Field = { val jclazz = classToJava(fld.owner.asClass) val jname = fld.name.dropLocal.toString - try jclazz getDeclaredField jname + try jclazz.getDeclaredField(jname) catch { - case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld) + case ex: NoSuchFieldException => jclazz.getDeclaredField(expandedName(fld)) } } /** The Java method corresponding to a given Scala method. - * - * @param meth The Scala method - */ + * + * @param meth + * The Scala method + */ def methodToJava(meth: MethodSymbol): Method = { val jclazz = classToJava(meth.owner.asClass) val paramClasses = transformedType(meth).paramTypes map typeToJavaClass @@ -166,24 +161,27 @@ trait SymbolErasures { this: Global => } /** The Java constructor corresponding to a given Scala constructor. - * - * @param constr The Scala constructor - */ + * + * @param constr + * The Scala constructor + */ def constructorToJava(constr: MethodSymbol): Constructor[_] = { val jclazz = classToJava(constr.owner.asClass) val paramClasses = transformedType(constr).paramTypes map typeToJavaClass val effectiveParamClasses = if (!constr.owner.owner.isStaticOwner) jclazz.getEnclosingClass +: paramClasses else paramClasses - jclazz getDeclaredConstructor (effectiveParamClasses: _*) + jclazz.getDeclaredConstructor(effectiveParamClasses: _*) } - def memberToJava(symbol: Symbol): Option[Member] = try symbol match { - case ms: MethodSymbol if ms.isConstructor => Some(constructorToJava(ms)) - case ms: MethodSymbol => Some(methodToJava(ms)) - case ts: TermSymbol if ts.isJava => Some(fieldToJava(ts)) - case _ => None - } catch { + def memberToJava(symbol: Symbol): Option[Member] = try + symbol match { + case ms: MethodSymbol if ms.isConstructor => Some(constructorToJava(ms)) + case ms: MethodSymbol => Some(methodToJava(ms)) + case ts: TermSymbol if ts.isJava => Some(fieldToJava(ts)) + case _ => None + } + catch { case _: ReflectiveOperationException => None } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateInterpolations.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateInterpolations.scala index 5bb87a2e..b722bd29 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateInterpolations.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateInterpolations.scala @@ -6,46 +6,33 @@ import com.avsystem.scex.compiler.annotation.NotValidated import scala.annotation.compileTimeOnly import scala.language.experimental.macros -/** - * Created: 18-11-2013 - * Author: ghik - */ +/** Created: 18-11-2013 Author: ghik + */ trait TemplateInterpolations[T] { implicit class TemplateInterpolation(sc: StringContext) { - /** - * String interpolation used to compile template expressions. - * Template expressions have form `part0${arg1}part1${arg2}part2...` where "parts" are plaintext - * fragments (unquoted string literals) and "args" are arbitrary subexpressions. - *

- * Template interpolation tries to concatenate `parts` and `args` according to following rules: - *

- * - * @return - */ + + /** String interpolation used to compile template expressions. Template expressions have form + * `part0${arg1}part1${arg2}part2...` where "parts" are plaintext fragments (unquoted string literals) and + * "args" are arbitrary subexpressions.

Template interpolation tries to concatenate `parts` and `args` + * according to following rules:

+ * + * @return + */ def t[A](args: A*): T = macro Macros.templateInterpolation_impl[T, A] // non-macro version of `t` used only in presentation compiler so that completer doesn't get confused @@ -72,8 +59,8 @@ object TemplateInterpolations { def concatIterator(parts: String*)(args: Iterator[Any]): String = { val sb = new StringBuilder(parts.head) - (args zip parts.tail.iterator).foreach { - case (arg, part) => sb.append(String.valueOf(arg)).append(part) + (args zip parts.tail.iterator).foreach { case (arg, part) => + sb.append(String.valueOf(arg)).append(part) } sb.result() } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateOptimizingScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateOptimizingScexCompiler.scala index 1e30db1c..b7331f65 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateOptimizingScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/TemplateOptimizingScexCompiler.scala @@ -15,19 +15,15 @@ import scala.annotation.tailrec import scala.util.control.NonFatal import scala.util.{Failure, Success, Try} -/** - * An extension of ScexCompiler which: - * - * - * - * Created: 01-04-2014 - * Author: ghik - */ +/** An extension of ScexCompiler which: + * + * + * + * Created: 01-04-2014 Author: ghik + */ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { import com.avsystem.scex.util.CacheImplicits._ @@ -43,8 +39,11 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { def apply(ctx: ExpressionContext[_, _]): Any = value } - private class OptimizedTemplateExpression(parts: List[String], args: List[RawExpression], val debugInfo: ExpressionDebugInfo) - extends RawExpression { + private class OptimizedTemplateExpression( + parts: List[String], + args: List[RawExpression], + val debugInfo: ExpressionDebugInfo, + ) extends RawExpression { def apply(c: ExpressionContext[_, _]): String = TemplateInterpolations.concatIterator(parts: _*)(args.iterator.map(_.apply(c))) @@ -52,19 +51,25 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { import com.avsystem.scex.parsing.TemplateParser.{parseTemplate, Success => ParsingSuccess} - /** - * Compiles a dummy expression that tests if there is a valid implicit conversion from Literal to expected type - * that is not a macro and does not reference context or root object (and thus is independent of expression input). - * If there is no such conversion, LiteralsOptimizingScexCompiler will not attempt to optimize the - * compilation and simply pass it to super.compileExpression. - */ + /** Compiles a dummy expression that tests if there is a valid implicit conversion from Literal to expected type that + * is not a macro and does not reference context or root object (and thus is independent of expression input). If + * there is no such conversion, LiteralsOptimizingScexCompiler will not attempt to optimize the + * compilation and simply pass it to super.compileExpression. + */ private def validateLiteralConversion(exprDef: ExpressionDef) = { import com.avsystem.scex.compiler.CodeGeneration._ val actualHeader = implicitLiteralViewHeader(exprDef.header) val validationExpression = implicitLiteralViewExpression(exprDef.resultType) - val validationExprDef = ExpressionDef(exprDef.profile, template = false, setter = false, validationExpression, - actualHeader, exprDef.contextType, exprDef.resultType, Map.empty)( - validationExpression, EmptyPositionMapping, exprDef.rootObjectClass) + val validationExprDef = ExpressionDef( + exprDef.profile, + template = false, + setter = false, + validationExpression, + actualHeader, + exprDef.contextType, + exprDef.resultType, + Map.empty, + )(validationExpression, EmptyPositionMapping, exprDef.rootObjectClass) super.compileExpression(validationExprDef) } @@ -73,7 +78,8 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { val profileObjectPkg = compileProfileObject(profile).get val utilsObjectPkg = compileExpressionUtils(profile.expressionUtils).get - val conversionClassCode = implicitLiteralConversionClass(profileObjectPkg, utilsObjectPkg, profile.expressionHeader, header, resultType) + val conversionClassCode = + implicitLiteralConversionClass(profileObjectPkg, utilsObjectPkg, profile.expressionHeader, header, resultType) val pkgName = ConversionSupplierPkgPrefix + DigestUtils.md5Hex(conversionClassCode) val fullCode = wrapInSource(conversionClassCode, pkgName) @@ -91,7 +97,11 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { } private def toCompileError(expr: String, resultType: String, throwable: Throwable) = - CompileError(expr, 1, s"Invalid literal value for $resultType: ${throwable.getClass.getName}: ${throwable.getMessage}") + CompileError( + expr, + 1, + s"Invalid literal value for $resultType: ${throwable.getClass.getName}: ${throwable.getMessage}", + ) private def isStringSupertype(tpe: String) = JavaTypeParsing.StringSupertypes.contains(tpe) @@ -114,7 +124,10 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { LiteralExpression(convertedValue)(debugInfo) } catch { case NonFatal(throwable) => - throw CompilationFailedException(singlePart, List(toCompileError(singlePart, exprDef.resultType, throwable))) + throw CompilationFailedException( + singlePart, + List(toCompileError(singlePart, exprDef.resultType, throwable)), + ) } } else super.compileExpression(exprDef) @@ -126,17 +139,29 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { val argExprTries = args.map { arg => val shift = SingleShiftPositionMapping(arg.beg) val reverseMapping = exprDef.positionMapping.reverse - val originalArg = exprDef.originalExpression.substring(reverseMapping(arg.beg), reverseMapping(arg.end - 1) + 1) - val shiftedMapping = shift andThen exprDef.positionMapping andThen shift.reverse + val originalArg = + exprDef.originalExpression.substring(reverseMapping(arg.beg), reverseMapping(arg.end - 1) + 1) + val shiftedMapping = shift.andThen(exprDef.positionMapping).andThen(shift.reverse) compileExpression( - ExpressionDef(exprDef.profile, template = true, setter = false, arg.result, exprDef.header, - exprDef.contextType, "String", exprDef.variableTypes)(originalArg, shiftedMapping, exprDef.rootObjectClass)) + ExpressionDef( + exprDef.profile, + template = true, + setter = false, + arg.result, + exprDef.header, + exprDef.contextType, + "String", + exprDef.variableTypes, + )(originalArg, shiftedMapping, exprDef.rootObjectClass) + ) } @tailrec def merge( - exprs: List[Try[RawExpression]], successAcc: List[RawExpression], errorsAcc: List[CompileError] + exprs: List[Try[RawExpression]], + successAcc: List[RawExpression], + errorsAcc: List[CompileError], ): Try[List[RawExpression]] = exprs match { case Success(expr) :: rest => @@ -163,19 +188,21 @@ trait TemplateOptimizingScexCompiler extends ScexPresentationCompiler { case Nil if exprDef.template && !exprDef.setter && !isStringSupertype(exprDef.resultType) => parseTemplate(exprDef.expression) match { case ParsingSuccess((List(singlePart), Nil), _) if validateLiteralConversion(exprDef).isSuccess => - getLiteralConversion(exprDef).map { conversion => - if (conversion.isNullable && singlePart.isEmpty) Nil - else { - val literal = Literal(singlePart) - try { - conversion.get.apply(literal) - Nil - } catch { - case NonFatal(ex) => - List(toCompileError(singlePart, exprDef.resultType, ex)) + getLiteralConversion(exprDef) + .map { conversion => + if (conversion.isNullable && singlePart.isEmpty) Nil + else { + val literal = Literal(singlePart) + try { + conversion.get.apply(literal) + Nil + } catch { + case NonFatal(ex) => + List(toCompileError(singlePart, exprDef.resultType, ex)) + } } } - }.getOrElse(Nil) + .getOrElse(Nil) case _ => Nil } @@ -203,4 +230,4 @@ object TemplateOptimizingScexCompiler { def checkConstant[T](expr: T): T = macro Macros.checkConstantExpr_impl[T] def isNullable[T]: Boolean = macro Macros.isNullable_impl[T] -} \ No newline at end of file +} diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/WeakReferenceWrappingScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/WeakReferenceWrappingScexCompiler.scala index 9b8f0d48..420d9108 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/WeakReferenceWrappingScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/WeakReferenceWrappingScexCompiler.scala @@ -4,20 +4,16 @@ package compiler import scala.ref.WeakReference import scala.util.Try -/** - * Wraps compiled expression into a wrapper that only holds weak reference to underlying expression. - * This is to allow actually compiled expression classes to be GCed after the compiler is reset. - * This trait should be used together with CachingScexCompiler to avoid recompilation of expressions - * every time GC wipes out the weak reference. - * - * Created: 02-04-2014 - * Author: ghik - */ +/** Wraps compiled expression into a wrapper that only holds weak reference to underlying expression. This is to allow + * actually compiled expression classes to be GCed after the compiler is reset. This trait should be used together with + * CachingScexCompiler to avoid recompilation of expressions every time GC wipes out the weak reference. + * + * Created: 02-04-2014 Author: ghik + */ trait WeakReferenceWrappingScexCompiler extends ScexCompiler { - /** - * Wrapper that avoids holding strong reference to actual compiled expression. - */ + /** Wrapper that avoids holding strong reference to actual compiled expression. + */ private class WeakExpressionWrapper(exprDef: ExpressionDef, initiallyWrapped: RawExpression) extends RawExpression { var expressionRef = new WeakReference(initiallyWrapped) diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/Input.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/Input.scala index 37882cfe..2dba2c62 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/Input.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/Input.scala @@ -2,8 +2,6 @@ package com.avsystem.scex.compiler.annotation import scala.annotation.StaticAnnotation -/** - * Created: 04-11-2014 - * Author: ghik +/** Created: 04-11-2014 Author: ghik */ -class Input extends StaticAnnotation \ No newline at end of file +class Input extends StaticAnnotation diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/NotValidated.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/NotValidated.scala index fc74196c..2e9ea02b 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/NotValidated.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/NotValidated.scala @@ -3,12 +3,10 @@ package compiler.annotation import scala.annotation.StaticAnnotation -/** - * Ident and Select trees whose symbol is annotated with this annotation will not be validated, along with the - * qualifier of Select. This is to mark symbols that serve as always-available API inside expressions, like root object - * or variable getters/setters. - * - * Created: 23-09-2013 - * Author: ghik - */ +/** Ident and Select trees whose symbol is annotated with this annotation will not be validated, along with the + * qualifier of Select. This is to mark symbols that serve as always-available API inside expressions, like root object + * or variable getters/setters. + * + * Created: 23-09-2013 Author: ghik + */ class NotValidated extends StaticAnnotation diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/RootValue.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/RootValue.scala index 08ac0270..1348a59e 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/RootValue.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/annotation/RootValue.scala @@ -1,7 +1,5 @@ package com.avsystem.scex.compiler.annotation -/** - * Author: ghik - * Created: 13/01/15. - */ +/** Author: ghik Created: 13/01/15. + */ class RootValue extends Input diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/CachingScexPresentationCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/CachingScexPresentationCompiler.scala index fb17dbcd..1c232ade 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/CachingScexPresentationCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/CachingScexPresentationCompiler.scala @@ -7,16 +7,14 @@ import java.{lang => jl, util => ju} import com.avsystem.scex.compiler.ExpressionDef import com.avsystem.scex.compiler.ScexCompiler.{CompilationFailedException, CompileError} -import com.avsystem.scex.compiler.presentation.ScexPresentationCompiler.{Member, Completion} +import com.avsystem.scex.compiler.presentation.ScexPresentationCompiler.{Completion, Member} import com.avsystem.scex.presentation.SymbolAttributes import com.avsystem.scex.util.TypeWrapper import com.google.common.cache.CacheBuilder import com.google.common.util.concurrent.ExecutionError -/** - * Created: 12-12-2013 - * Author: ghik - */ +/** Created: 12-12-2013 Author: ghik + */ trait CachingScexPresentationCompiler extends ScexPresentationCompiler { import com.avsystem.scex.util.CommonUtils._ @@ -38,8 +36,7 @@ trait CachingScexPresentationCompiler extends ScexPresentationCompiler { .maximumSize(settings.typeMembersCacheSize.value) .build[TypeMembersCacheKey, Vector[Member]] - private val symbolAttributesCache = CacheBuilder.newBuilder - .build[String, SymbolAttributes] + private val symbolAttributesCache = CacheBuilder.newBuilder.build[String, SymbolAttributes] override protected def getErrors(exprDef: ExpressionDef) = unwrapExecutionException(errorsCache.get(exprDef, callable(super.getErrors(exprDef)))) @@ -47,8 +44,14 @@ trait CachingScexPresentationCompiler extends ScexPresentationCompiler { override protected def getScopeCompletion(exprDef: ExpressionDef) = unwrapExecutionException(scopeCompletionCache.get(exprDef, callable(super.getScopeCompletion(exprDef)))) - override protected def getTypeMembers(global: IGlobal)(exprDef: ExpressionDef, ownerTpe: global.Type) - (computeMembers: => Vector[Member]): Vector[Member] = { + override protected def getTypeMembers( + global: IGlobal + )( + exprDef: ExpressionDef, + ownerTpe: global.Type, + )( + computeMembers: => Vector[Member] + ): Vector[Member] = { val key = TypeMembersCacheKey(exprDef.profile, exprDef.contextType, TypeWrapper(global)(ownerTpe.map(_.widen))) unwrapExecutionException(typeMembersCache.get(key, callable(computeMembers))) @@ -66,7 +69,8 @@ trait CachingScexPresentationCompiler extends ScexPresentationCompiler { } private def unwrapExecutionException[T](code: => T) = - try code catch { + try code + catch { case e: ExecutionException => throw e.getCause case e: ExecutionError => throw e.getCause } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/IGlobal.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/IGlobal.scala index f5837e04..3d34ee69 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/IGlobal.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/IGlobal.scala @@ -10,8 +10,7 @@ import scala.tools.nsc.interactive.Global import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.symtab.Flags.{ACCESSOR, PARAMACCESSOR} -/** - * I needed to hack a custom implementation of completion, hence this class. +/** I needed to hack a custom implementation of completion, hence this class. */ @nowarn("msg=deprecated") class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoader) @@ -35,14 +34,14 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad tpe: Type, accessible: Boolean, implicitTree: Tree, - implicitType: Type + implicitType: Type, ) extends ScexMember case class ScexScopeMember( sym: Symbol, tpe: Type, accessible: Boolean, - viaImport: Tree + viaImport: Tree, ) extends ScexMember { def prefix: Type = viaImport.tpe def implicitTree: Tree = EmptyTree @@ -53,7 +52,7 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad override def default(key: Name) = Set() private def matching(sym: Symbol, symtpe: Type, ms: Set[T]): Option[T] = ms.find { m => - (m.sym.name == sym.name) && (m.sym.isType || (m.tpe matches symtpe)) + (m.sym.name == sym.name) && (m.sym.isType || (m.tpe.matches(symtpe))) } private def keepSecond(m: T, sym: Symbol, implicitTree: Tree): Boolean = { @@ -63,7 +62,8 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad if (symbol.isType) symbol.asType.toType.baseClasses match { case _ :: tail => tail.toSet case Nil => Set.empty - } else Set.empty + } + else Set.empty def argumentType(tpe: Type) = tpe match { case MethodType(List(param), _) => param.typeSignature @@ -75,7 +75,8 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad lazy val higherPriorityImplicit = m.implicitlyAdded && implicitlyAdded && { val specificityPoints = compare(argumentType(implicitTree.tpe), argumentType(m.implicitTree.tpe))(_ <:< _) - val priorityPoints = compare(implicitTree.symbol.owner, m.implicitTree.symbol.owner)((s1, s2) => superclasses(s1).contains(s2)) + val priorityPoints = + compare(implicitTree.symbol.owner, m.implicitTree.symbol.owner)((s1, s2) => superclasses(s1).contains(s2)) specificityPoints + priorityPoints > 0 } @@ -87,21 +88,21 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad if (sym.hasGetter) { add(sym.getterIn(sym.owner), pre, implicitTree)(toMember) } else if (!sym.name.decodedName.containsName("$") && !sym.isError && !sym.isArtifact && sym.hasRawInfo) { - val symtpe = pre.memberType(sym) onTypeError ErrorType - matching(sym, symtpe, this (sym.name)) match { + val symtpe = pre.memberType(sym).onTypeError(ErrorType) + matching(sym, symtpe, this(sym.name)) match { case Some(m) => if (keepSecond(m, sym, implicitTree)) { - this (sym.name) = this (sym.name) - m + toMember(sym, symtpe) + this(sym.name) = this(sym.name) - m + toMember(sym, symtpe) } case None => - this (sym.name) = this (sym.name) + toMember(sym, symtpe) + this(sym.name) = this(sym.name) + toMember(sym, symtpe) } } } def addNonShadowed(other: Members[T]): Unit = { for ((name, ms) <- other) - if (ms.nonEmpty && this (name).isEmpty) this (name) = ms + if (ms.nonEmpty && this(name).isEmpty) this(name) = ms } def allMembers: Vector[T] = values.toVector.flatten @@ -153,8 +154,9 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad object ErroneousSelectDynamic { def unapply(tree: Tree): Option[(Tree, Literal)] = tree match { case Select(qual, name) - if (tree.tpe == ErrorType || tree.tpe == null) && qual.tpe != null && qual.tpe != ErrorType && qual.tpe <:< dynamicTpe => - val literalPos = tree.pos.withStart(tree.pos.end min (qual.pos.end + 1)).makeTransparent + if (tree.tpe == ErrorType || tree.tpe == null) && qual.tpe != null && qual.tpe != ErrorType && + qual.tpe <:< dynamicTpe => + val literalPos = tree.pos.withStart(tree.pos.end.min(qual.pos.end + 1)).makeTransparent val literal = Literal(Constant(name.decoded)).setPos(literalPos) Some((qual, literal)) case _ => @@ -206,7 +208,9 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad preFixed match { case ErroneousSelectDynamic(newQual, literal) => - retypeQual(Apply(Select(newQual, TermName("selectDynamic")).setPos(newQual.pos), List(literal)).setPos(tree.pos)) + retypeQual( + Apply(Select(newQual, TermName("selectDynamic")).setPos(newQual.pos), List(literal)).setPos(tree.pos) + ) case _ => preFixed } @@ -218,7 +222,8 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad // now, drop incomplete selection tree match { - case Select(qual, _) if tree.tpe == ErrorType && !(qual.tpe != null && qual.tpe != ErrorType && qual.tpe <:< dynamicTpe) => + case Select(qual, _) + if tree.tpe == ErrorType && !(qual.tpe != null && qual.tpe != ErrorType && qual.tpe <:< dynamicTpe) => tree = qual case SelectDynamic(qual, "") => tree = qual @@ -243,7 +248,7 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad Ident(nme.EMPTY).setSymbol(Option(symbol).getOrElse(NoSymbol)).setType(tpe) val forValidation = tree match { - case Select(apply@ImplicitlyConverted(qual, fun), name) => + case Select(apply @ ImplicitlyConverted(qual, fun), name) => treeCopy.Select(tree, treeCopy.Apply(apply, fun, List(fakeIdent(qual.tpe, qual.symbol))), name) case Select(qual, name) => treeCopy.Select(tree, fakeIdent(qual.tpe, qual.symbol), name) @@ -277,13 +282,10 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad TypeCompletionContext(context, tree, pre, ownerTpe) } - /** - * Reimplementation of `scala.tools.interactive.Global.typeMembers` method, adjusted to SCEX needs: - * + /** Reimplementation of `scala.tools.interactive.Global.typeMembers` method, adjusted to SCEX needs: */ def typeMembers(completionContext: TypeCompletionContext): Vector[ScexTypeMember] = { val TypeCompletionContext(context, tree, pre, ownerTpe) = completionContext @@ -294,9 +296,14 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad def addTypeMember(sym: Symbol, pre: Type, implicitTree: Tree, implicitType: Type): Unit = { val implicitlyAdded = implicitTree != EmptyTree members.add(sym, pre, implicitTree) { (s, st) => - ScexTypeMember(ownerTpe, s, st, + ScexTypeMember( + ownerTpe, + s, + st, context.isAccessible(if (s.hasGetter) s.getterIn(s.owner) else s, pre, superAccess && !implicitlyAdded), - implicitTree, implicitType) + implicitTree, + implicitType, + ) } } @@ -305,8 +312,9 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad */ def viewApply(view: analyzer.SearchResult): Tree = { assert(view.tree != EmptyTree, "") - analyzer.newTyper(context.makeImplicit(reportAmbiguousErrors = false)) - .typed(Apply(view.tree, List(tree)) setPos tree.pos) + analyzer + .newTyper(context.makeImplicit(reportAmbiguousErrors = false)) + .typed(Apply(view.tree, List(tree)).setPos(tree.pos)) .onTypeError(EmptyTree) } @@ -315,9 +323,13 @@ class IGlobal(settings: Settings, reporter: Reporter, val classLoader: ClassLoad val applicableViews: List[analyzer.SearchResult] = if (ownerTpe.isErroneous || ownerTpe <:< NullTpe || ownerTpe <:< NothingTpe) List() - else new analyzer.ImplicitSearch( - tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true, - context0 = context.makeImplicit(reportAmbiguousErrors = false)).allImplicits + else + new analyzer.ImplicitSearch( + tree, + functionType(List(ownerTpe), AnyClass.tpe), + isView = true, + context0 = context.makeImplicit(reportAmbiguousErrors = false), + ).allImplicits for (view <- applicableViews) { val vtree = viewApply(view) diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ScexPresentationCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ScexPresentationCompiler.scala index 7c305bdc..1d88af37 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ScexPresentationCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ScexPresentationCompiler.scala @@ -6,7 +6,7 @@ import com.avsystem.commons.jiop.JavaInterop._ import com.avsystem.commons.misc.TypeString import com.avsystem.scex.compiler.CodeGeneration._ import com.avsystem.scex.compiler.ScexCompiler.{CompilationFailedException, CompileError} -import com.avsystem.scex.compiler.presentation.ScexPresentationCompiler.{Completion, MemberFlags, Param, Member => SMember} +import com.avsystem.scex.compiler.presentation.ScexPresentationCompiler.{Completion, Member => SMember, MemberFlags, Param} import com.avsystem.scex.compiler.{ExpressionDef, _} import com.avsystem.scex.parsing.EmptyPositionMapping import com.avsystem.scex.presentation.annotation.{Documentation, ParameterNames} @@ -44,16 +44,17 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => case Right(t) => throw t } - private def inCompilerThread[T](code: => T) = { + private def inCompilerThread[T](code: => T) = getOrThrow(global.askForResponse(() => code)) - } protected final def withIGlobal[T](code: IGlobal => T) = underLock { reporter.reset() val global = compiler.global - val result = try code(global) finally { - reporter.reset() - } + val result = + try code(global) + finally { + reporter.reset() + } result } @@ -65,7 +66,7 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => contextType: String, rootObjectClass: Class[_], resultType: String, - variableTypes: Map[String, String] + variableTypes: Map[String, String], ) { require(profile != null, "Profile cannot be null") @@ -77,15 +78,24 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => val (actualExpression, positionMapping) = if (bare) (expression, EmptyPositionMapping) else preprocess(expression, template) - ExpressionDef(profile, template && !bare, setter && !bare, actualExpression, header, contextType, - if (bare) "Any" else resultType, variableTypes)(expression, positionMapping, rootObjectClass) + ExpressionDef( + profile, + template && !bare, + setter && !bare, + actualExpression, + header, + contextType, + if (bare) "Any" else resultType, + variableTypes, + )(expression, positionMapping, rootObjectClass) } // sometimes presentation compiler just fails to typecheck things and crashes // until we know what's happening it's better to return some default value (e.g. empty completion) // instead of crashing private def workaroundAssertionError[T](expr: => T, default: T): T = - try expr catch { + try expr + catch { case e: AssertionError => logger.error(s"Presentation compiler crashed, returning $default", e) default @@ -112,14 +122,13 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => template: Boolean = true, setter: Boolean = false, variableTypes: Map[String, TypeString[_]] = Map.empty, - header: String = "" - )( - implicit + header: String = "", + )(implicit cti: ContextTypeInfo[C], - tts: TypeString[T] + tts: TypeString[T], ): Completer = { - val strVariableTypes = variableTypes.iterator.map({ case (k, v) => (k, v.value) }).toMap + val strVariableTypes = variableTypes.iterator.map { case (k, v) => (k, v.value) }.toMap getCompleter(profile, template, setter, header, cti.fullTypeString, cti.rootObjectClass, tts.value, strVariableTypes) } @@ -131,11 +140,10 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => contextType: String, rootObjectClass: Class[_], resultType: String, - variableTypes: Map[String, String] - ): Completer = { + variableTypes: Map[String, String], + ): Completer = new Completer(profile, template, setter, header, contextType, rootObjectClass, resultType, variableTypes) - } private def getContextTpe(global: IGlobal)(tree: global.Tree): global.Type = { import global._ @@ -189,21 +197,20 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => case _ => None } - def parseAnnotation(ann: Annotation): Attributes = { + def parseAnnotation(ann: Annotation): Attributes = if (ann.tree.tpe <:< typeOf[ParameterNames]) { - val paramNames = annotValue(ann.tree).map { - case Apply(_, paramNameLiterals) => paramNameLiterals.map { - case LiteralString(name) => name + val paramNames = annotValue(ann.tree).map { case Apply(_, paramNameLiterals) => + paramNameLiterals.map { case LiteralString(name) => + name } } new Attributes(paramNames, None) } else if (ann.tree.tpe <:< typeOf[Documentation]) { - val documentation = annotValue(ann.tree).map { - case LiteralString(doc) => doc + val documentation = annotValue(ann.tree).map { case LiteralString(doc) => + doc } new Attributes(None, documentation) } else Attributes.empty - } def attributesFromAnnotations = withOverrides(m.sym).iterator.flatMap(s => annotations(s)).map(parseAnnotation).toStream @@ -213,7 +220,7 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => case Stream.Empty => Attributes.empty } - foldAttributes(attributesFromInfos append attributesFromAnnotations) + foldAttributes(attributesFromInfos.append(attributesFromAnnotations)) } private def translateMember(global: IGlobal, attrs: SymbolAttributes)(member: global.ScexMember) = { @@ -221,9 +228,12 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => def translateType(tpe: Type) = if (tpe == NoType) SType.NoType - else tpe.toOpt.map { tpe => - SType(tpe.map(_.dealiasWiden).toString(), erasureClass(tpe)) - }.getOrElse(SType.NoType) + else + tpe.toOpt + .map { tpe => + SType(tpe.map(_.dealiasWiden).toString(), erasureClass(tpe)) + } + .getOrElse(SType.NoType) val attributes = getAttributes(global, attrs)(member) val (params, implParams) = paramsOf(member.tpe) @@ -239,14 +249,16 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => val javaMember = memberToJava(if (adapter) getJavaGetter(member.sym, adaptedType) else member.sym) val rootMember = isAnnotatedWith(member.ownerTpe.widen, rootValueAnnotType) - SMember(member.sym.decodedName, + SMember( + member.sym.decodedName, params.map(_.map(symbolToParam)), implParams.map(symbolToParam), translateType(member.ownerTpe), translateType(member.tpe.finalResultType), MemberFlags(member.sym.isImplicit, adapter, rootMember), javaMember, - attributes.documentation) + attributes.documentation, + ) } protected def getErrors(exprDef: ExpressionDef) = withIGlobal { global => @@ -291,7 +303,7 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => val scope: Vector[ScexScopeMember] = scopeMembers(pos) val membersIterator = scope.iterator.filter { m => m.viaImport != EmptyTree && m.sym.isTerm && !m.sym.hasPackageFlag && !isFromProfileObject(m.sym) && - symbolValidator.validateMemberAccess(vc)(accessFromScopeMember(m)).deniedAccesses.isEmpty + symbolValidator.validateMemberAccess(vc)(accessFromScopeMember(m)).deniedAccesses.isEmpty } map translateMember(global, symbolAttributes) Completion(ast.EmptyTree, membersIterator.toVector) @@ -323,12 +335,12 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => // treat keywords incorrectly typed after dot as part of the Select tree case Select(_, termNames.ERROR) => val chars = sourceFile.content - val newEnd = tree.pos.end + Iterator.range(tree.pos.end, chars.length) - .takeWhile(i => chars(i).isLetter).length + val newEnd = tree.pos.end + + Iterator.range(tree.pos.end, chars.length).takeWhile(i => chars(i).isLetter).length tree.setPos(tree.pos.withEnd(newEnd)) // fix selectDynamic positions, which scalac computes incorrectly... - case tree@Apply(Select(_, TermName("selectDynamic")), List(lit@Literal(Constant(_: String)))) - if lit.pos.isTransparent && lit.pos.end >= tree.pos.end => + case tree @ Apply(Select(_, TermName("selectDynamic")), List(lit @ Literal(Constant(_: String)))) + if lit.pos.isTransparent && lit.pos.end >= tree.pos.end => tree.setPos(tree.pos.withEnd(lit.pos.end)) case _ => } @@ -346,7 +358,7 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => } } - val result = { + val result = try { val sourcePosition = sourceFile.position(offset + exprDef.positionMapping(position)) @@ -360,14 +372,20 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => inCompilerThread { positionFixer.traverse(fullTree) - val tree = new ScexLocator(sourcePosition).locateIn(fullTree).toOpt - .filter(t => t.pos != NoPosition && t.pos.start >= offset).getOrElse(EmptyTree) + val tree = new ScexLocator(sourcePosition) + .locateIn(fullTree) + .toOpt + .filter(t => t.pos != NoPosition && t.pos.start >= offset) + .getOrElse(EmptyTree) def isAllowed(tree: Tree) = symbolValidator.validateMemberAccess(vc)(extractAccess(tree)).deniedAccesses.isEmpty val completionCtx = global.typeCompletionContext(tree, sourcePosition, isAllowed) - logger.debug("Prefix tree for type completion:\n" + show(completionCtx.prefixTree, printTypes = true, printPositions = true)) + logger.debug( + "Prefix tree for type completion:\n" + + show(completionCtx.prefixTree, printTypes = true, printPositions = true) + ) val members = getTypeMembers(global)(exprDef, completionCtx.ownerTpe) { val typeMembers = global.typeMembers(completionCtx) @@ -380,14 +398,18 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => def fakeSelect(member: ScexTypeMember) = { val fakePrefix = if (!member.implicitlyAdded) fakeDirectPrefix - else Apply(member.implicitTree, List(fakeDirectPrefix)) - .setSymbol(member.implicitTree.symbol).setType(member.implicitType) + else + Apply(member.implicitTree, List(fakeDirectPrefix)) + .setSymbol(member.implicitTree.symbol) + .setType(member.implicitType) Select(fakePrefix, member.sym) } typeMembers.collect { - case m if m.sym.isTerm && m.sym.isPublic && !m.sym.isConstructor - && !isAdapterWrappedMember(m.sym) && isAllowed(fakeSelect(m)) => translateMember(global, symbolAttributes)(m) + case m + if m.sym.isTerm && m.sym.isPublic && !m.sym.isConstructor && !isAdapterWrappedMember(m.sym) && + isAllowed(fakeSelect(m)) => + translateMember(global, symbolAttributes)(m) } } @@ -402,7 +424,6 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => global.askFilesDeleted(List(sourceFile), resp) getOrThrow(resp) } - } val duration = System.nanoTime() - startTime logger.debug(s"Completion took ${duration / 1000000}ms") @@ -411,8 +432,14 @@ trait ScexPresentationCompiler extends ScexCompiler { compiler => } // method extracted in order to make it possible to cache results by some other trait - protected def getTypeMembers(global: IGlobal)(exprDef: ExpressionDef, ownerTpe: global.Type) - (computeMembers: => Vector[SMember]): Vector[SMember] = computeMembers + protected def getTypeMembers( + global: IGlobal + )( + exprDef: ExpressionDef, + ownerTpe: global.Type, + )( + computeMembers: => Vector[SMember] + ): Vector[SMember] = computeMembers protected def parse(exprDef: ExpressionDef) = withIGlobal { global => inCompilerThread { @@ -469,8 +496,14 @@ object ScexPresentationCompiler { final case class MemberFlags(iimplicit: Boolean, javaGetterAdapter: Boolean, inputMember: Boolean) final case class Member( - name: String, params: List[List[Param]], implicitParams: List[Param], ownerType: Type, returnType: Type, - flags: MemberFlags, javaMember: Option[jl.reflect.Member], documentation: Option[String] + name: String, + params: List[List[Param]], + implicitParams: List[Param], + ownerType: Type, + returnType: Type, + flags: MemberFlags, + javaMember: Option[jl.reflect.Member], + documentation: Option[String], ) { def paramsAsJava = diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Attachments.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Attachments.scala index daa59ed3..a0cd81a4 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Attachments.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Attachments.scala @@ -3,10 +3,8 @@ package compiler.presentation.ast import com.avsystem.commons.jiop.JavaInterop._ -/** - * Created: 12-03-2014 - * Author: ghik - */ +/** Created: 12-03-2014 Author: ghik + */ final case class Attachments(tpe: Type, position: Position) object Attachments { val empty = new Attachments(Type.NoType, null) diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Flags.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Flags.scala index b8414248..5fb250ea 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Flags.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Flags.scala @@ -3,10 +3,8 @@ package compiler.presentation.ast import scala.reflect.internal.ModifierFlags -/** - * Created: 12-03-2014 - * Author: ghik - */ +/** Created: 12-03-2014 Author: ghik + */ final case class Flags(flags: Long)(flagString: String) { private def hasFlag(flag: Long) = (flags & flag) != 0 diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Modifiers.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Modifiers.scala index dd09ee70..4aea7801 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Modifiers.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Modifiers.scala @@ -3,10 +3,8 @@ package compiler.presentation.ast import com.avsystem.commons.jiop.JavaInterop._ -/** - * Created: 12-03-2014 - * Author: ghik - */ +/** Created: 12-03-2014 Author: ghik + */ final case class Modifiers(flags: Flags, privateWithin: Name, annotations: List[Tree]) extends PrettyPrint { def annotationsAsJava: JList[Tree] = annotations.asJava } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/PrettyPrint.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/PrettyPrint.scala index 4252c737..b6e7403f 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/PrettyPrint.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/PrettyPrint.scala @@ -1,8 +1,6 @@ package com.avsystem.scex package compiler.presentation.ast -/** - * Created: 13-03-2014 - * Author: ghik - */ +/** Created: 13-03-2014 Author: ghik + */ trait PrettyPrint extends Product diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Translator.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Translator.scala index 723bd5ca..1d0eedc7 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Translator.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Translator.scala @@ -4,10 +4,8 @@ package compiler.presentation.ast import com.avsystem.scex.compiler.{ExpressionDef, ScexGlobal} import com.avsystem.scex.util.MacroUtils -/** - * Created: 12-03-2014 - * Author: ghik - */ +/** Created: 12-03-2014 Author: ghik + */ class Translator(val global: ScexGlobal, offset: Int, exprDef: ExpressionDef) extends MacroUtils { val universe: global.type = global val u: universe.type = universe @@ -62,16 +60,32 @@ class Translator(val global: ScexGlobal, offset: Int, exprDef: ExpressionDef) ex case u.LabelDef(name, params, rhs) => LabelDef(translateTermName(name), params.map(translateTreeIn[Ident]), translateTree(rhs))(attachments) case u.ClassDef(mods, name, tparams, impl) => - ClassDef(translateModifiers(mods), translateTypeName(name), tparams.map(translateTreeIn[TypeDef]), translateTreeIn[Template](impl))(attachments) + ClassDef( + translateModifiers(mods), + translateTypeName(name), + tparams.map(translateTreeIn[TypeDef]), + translateTreeIn[Template](impl), + )(attachments) case u.ModuleDef(mods, name, impl) => ModuleDef(translateModifiers(mods), translateTermName(name), translateTreeIn[Template](tree))(attachments) case u.PackageDef(pid, stats) => PackageDef(translateTreeIn[RefTree](pid), stats.map(translateTree))(attachments) case u.TypeDef(mods, name, tparams, rhs) => - TypeDef(translateModifiers(mods), translateTypeName(name), tparams.map(translateTreeIn[TypeDef]), translateTree(rhs))(attachments) + TypeDef( + translateModifiers(mods), + translateTypeName(name), + tparams.map(translateTreeIn[TypeDef]), + translateTree(rhs), + )(attachments) case u.DefDef(mods, name, tparams, vparamss, tpt, rhs) => - DefDef(translateModifiers(mods), translateName(name), tparams.map(translateTreeIn[TypeDef]), - vparamss.map(_.map(translateTreeIn[ValDef])), translateTree(tpt), translateTree(rhs))(attachments) + DefDef( + translateModifiers(mods), + translateName(name), + tparams.map(translateTreeIn[TypeDef]), + vparamss.map(_.map(translateTreeIn[ValDef])), + translateTree(tpt), + translateTree(rhs), + )(attachments) case u.Import(expr, selectors) => Import(translateTree(expr), selectors.map(translateImportSelector))(attachments) case u.Return(expr) => @@ -110,7 +124,7 @@ class Translator(val global: ScexGlobal, offset: Int, exprDef: ExpressionDef) ex SingletonTypeTree(translateTree(ref))(attachments) case u.TypeBoundsTree(lo, hi) => TypeBoundsTree(translateTree(lo), translateTree(hi))(attachments) - case tt@u.TypeTree() => + case tt @ u.TypeTree() => TypeTree()(translateTree(tt.original), attachments) case _ => throw new IllegalArgumentException(s"Unknown tree: ${u.showRaw(tree)}") @@ -128,10 +142,13 @@ class Translator(val global: ScexGlobal, offset: Int, exprDef: ExpressionDef) ex Constant(c.value)(c.escapedStringValue) def translateType(tpe: u.Type): Type = - if(tpe == u.NoType) Type.NoType - else tpe.toOpt.map { tpe => - Type(tpe.map(_.dealiasWiden).toString(), u.erasureClass(tpe)) - }.getOrElse(Type.NoType) + if (tpe == u.NoType) Type.NoType + else + tpe.toOpt + .map { tpe => + Type(tpe.map(_.dealiasWiden).toString(), u.erasureClass(tpe)) + } + .getOrElse(Type.NoType) def translateAttachments(tree: u.Tree) = new Attachments(translateType(tree.tpe), translatePosition(tree.pos)) @@ -173,10 +190,12 @@ class Translator(val global: ScexGlobal, offset: Int, exprDef: ExpressionDef) ex def translatePosition(pos: u.Position): Position = pos match { case u.NoPosition | null => null - case _ => Position( - reverseMapping(math.max(pos.start, offset) - offset), - reverseMapping(math.min(pos.end, offset + exprDef.expression.length) - offset - 1) + 1, - pos.isTransparent) + case _ => + Position( + reverseMapping(math.max(pos.start, offset) - offset), + reverseMapping(math.min(pos.end, offset + exprDef.expression.length) - offset - 1) + 1, + pos.isTransparent, + ) } def translateModifiers(mods: u.Modifiers) = diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Tree.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Tree.scala index aa9b5f73..248e449f 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Tree.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/presentation/ast/Tree.scala @@ -24,7 +24,7 @@ sealed trait Tree extends PrettyPrint { def locate(start: Int, end: Int): Tree = locate(Position(start, end, transparent = false)) - def locate(pos: Position): Tree = { + def locate(pos: Position): Tree = if (pos != null) { var result: Tree = EmptyTree def traverse(tree: Tree): Unit = { @@ -32,7 +32,9 @@ sealed trait Tree extends PrettyPrint { case EmptyTree => case tt: TypeTree if tt.original != null && tt.original.attachments.position.includes(pos) => traverse(tt.original) - case _ if tree.attachments != null && tree.attachments.position != null && tree.attachments.position.includes(pos) => + case _ + if tree.attachments != null && tree.attachments.position != null && + tree.attachments.position.includes(pos) => if (!tree.attachments.position.transparent) { result = tree } @@ -45,7 +47,6 @@ sealed trait Tree extends PrettyPrint { traverse(this) result } else EmptyTree - } def pretty(withPositions: Boolean, withTypes: Boolean): String = { val sb = new StringBuilder @@ -102,10 +103,9 @@ sealed trait Tree extends PrettyPrint { abstract class AbstractTree(val attachments: Attachments) extends Tree -/** - * A Scex-specific tree which is just a nicer representation of template expression. - * This tree does not exist in the Scala compiler API. - */ +/** A Scex-specific tree which is just a nicer representation of template expression. This tree does not exist in the + * Scala compiler API. + */ final case class TemplateInterpolation(parts: List[Literal], args: List[Tree])(attachments: Attachments) extends AbstractTree(attachments) with TermTree { @@ -114,16 +114,13 @@ final case class TemplateInterpolation(parts: List[Literal], args: List[Tree])(a def argsAsJava = args.asJava } -final case class Annotated(annot: Tree, arg: Tree)(attachments: Attachments) - extends AbstractTree(attachments) +final case class Annotated(annot: Tree, arg: Tree)(attachments: Attachments) extends AbstractTree(attachments) -final case class CaseDef(pat: Tree, guard: Tree, body: Tree)(attachments: Attachments) - extends AbstractTree(attachments) +final case class CaseDef(pat: Tree, guard: Tree, body: Tree)(attachments: Attachments) extends AbstractTree(attachments) sealed trait DefTree extends NameTree -final case class Bind(name: Name, body: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with DefTree +final case class Bind(name: Name, body: Tree)(attachments: Attachments) extends AbstractTree(attachments) with DefTree final case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)(attachments: Attachments) extends AbstractTree(attachments) with DefTree with TermTree { @@ -139,8 +136,15 @@ sealed trait ImplDef extends MemberDef { def impl: Template } -final case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)(attachments: Attachments) - extends AbstractTree(attachments) with ImplDef { +final case class ClassDef( + mods: Modifiers, + name: TypeName, + tparams: List[TypeDef], + impl: Template, +)( + attachments: Attachments +) extends AbstractTree(attachments) + with ImplDef { def tparamsAsJava: JList[TypeDef] = tparams.asJava } @@ -170,8 +174,17 @@ sealed trait ValOrDefDef extends MemberDef { def rhs: Tree } -final case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], - tpt: Tree, rhs: Tree)(attachments: Attachments) extends AbstractTree(attachments) with ValOrDefDef { +final case class DefDef( + mods: Modifiers, + name: Name, + tparams: List[TypeDef], + vparamss: List[List[ValDef]], + tpt: Tree, + rhs: Tree, +)( + attachments: Attachments +) extends AbstractTree(attachments) + with ValOrDefDef { def tparamsAsJava: JList[TypeDef] = tparams.asJava @@ -195,8 +208,7 @@ final case class Import(expr: Tree, selectors: List[ImportSelector])(attachments def selectorsAsJava = selectors.asJava } -final case class Return(expr: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class Return(expr: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class Template(parents: List[Tree], self: ValDef, body: List[Tree])(attachments: Attachments) extends AbstractTree(attachments) { @@ -206,15 +218,13 @@ final case class Template(parents: List[Tree], self: ValDef, body: List[Tree])(a def bodyAsJava = body.asJava } -final case class This(qual: TypeName)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class This(qual: TypeName)(attachments: Attachments) extends AbstractTree(attachments) with TermTree sealed trait RefTree extends NameTree { def qualifier: Tree } -final case class Ident(name: Name)(attachments: Attachments) - extends AbstractTree(attachments) with RefTree { +final case class Ident(name: Name)(attachments: Attachments) extends AbstractTree(attachments) with RefTree { override def qualifier = EmptyTree } @@ -237,8 +247,7 @@ final case class Alternative(trees: List[Tree])(attachments: Attachments) def treesAsJava: JList[Tree] = trees.asJava } -final case class Assign(lhs: Tree, rhs: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class Assign(lhs: Tree, rhs: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class NamedArg(lhs: Tree, rhs: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree @@ -282,20 +291,17 @@ final case class Match(selector: Tree, cases: List[CaseDef])(attachments: Attach def casesAsJava: JList[CaseDef] = cases.asJava } -final case class New(tpt: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class New(tpt: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class ReferenceToBoxed(ident: Ident)(attachments: Attachments) extends AbstractTree(attachments) with TermTree -final case class Star(elem: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class Star(elem: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class Super(qual: Tree, mix: TypeName)(attachments: Attachments) extends AbstractTree(attachments) with TermTree -final case class Throw(expr: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class Throw(expr: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree { @@ -303,8 +309,7 @@ final case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)(attac def catchesAsJava: JList[CaseDef] = catches.asJava } -final case class Typed(expr: Tree, tpt: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TermTree +final case class Typed(expr: Tree, tpt: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TermTree final case class UnApply(fun: Tree, args: List[Tree])(attachments: Attachments) extends AbstractTree(attachments) with TermTree { @@ -335,11 +340,9 @@ final case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])(attach def whereClausesAsJava: JList[Tree] = whereClauses.asJava } -final case class SingletonTypeTree(ref: Tree)(attachments: Attachments) - extends AbstractTree(attachments) with TypTree +final case class SingletonTypeTree(ref: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TypTree final case class TypeBoundsTree(lo: Tree, hi: Tree)(attachments: Attachments) extends AbstractTree(attachments) with TypTree -final case class TypeTree()(val original: Tree, attachments: Attachments) - extends AbstractTree(attachments) with TypTree +final case class TypeTree()(val original: Tree, attachments: Attachments) extends AbstractTree(attachments) with TypTree diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyScexCompiler.scala index a0dc92c9..1f489901 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyScexCompiler.scala @@ -4,24 +4,17 @@ package compiler.xmlfriendly import com.avsystem.scex.compiler.ScexCompiler import com.avsystem.scex.parsing.PositionMapping -/** - * - * Scex compiler that accepts modified, XML-friendly syntax: - * - * - * Created: 16-08-2013 - * Author: ghik - */ +/** Scex compiler that accepts modified, XML-friendly syntax: + * + * Created: 16-08-2013 Author: ghik + */ trait XmlFriendlyScexCompiler extends ScexCompiler { override protected def preprocess(expression: String, template: Boolean): (String, PositionMapping) = { val (superExpression, superMapping) = super.preprocess(expression, template) val ps = XmlFriendlyTranslator.translate(superExpression, template) - (ps.result, ps.positionMapping andThen superMapping) + (ps.result, ps.positionMapping.andThen(superMapping)) } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslator.scala b/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslator.scala index 6a4c858a..6d576a2f 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslator.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslator.scala @@ -5,16 +5,21 @@ import com.avsystem.scex.compiler.CodeGeneration import com.avsystem.scex.parsing.{Binding, PString, PositionTrackingParsers} import com.avsystem.scex.util.CommonUtils._ -/** - * Parser that translates XML-friendly expressions into correct scala code. - * Implemented using Scala parser combinators (recursive descent parser). +/** Parser that translates XML-friendly expressions into correct scala code. Implemented using Scala parser combinators + * (recursive descent parser). * - * Created: 17-09-2013 - * Author: ghik + * Created: 17-09-2013 Author: ghik */ object XmlFriendlyTranslator extends PositionTrackingParsers { final val AllowedKeywords = Set( - "case", "else", "false", "if", "match", "new", "null", "true" + "case", + "else", + "false", + "if", + "match", + "new", + "null", + "true", ) final val XmlFriendlyOperators = Map( @@ -23,7 +28,7 @@ object XmlFriendlyTranslator extends PositionTrackingParsers { "lte" -> "<= ", "gte" -> ">= ", "and" -> "&& ", - "or" -> "||" + "or" -> "||", ).withDefault(identity) def escapeIdent(pstr: PString): PString = @@ -71,8 +76,8 @@ object XmlFriendlyTranslator extends PositionTrackingParsers { def number: Parser[PString] = "[0-9]+".rp - def block: Parser[PString] = "{".p ~ standardExpression ~ "}".p ^^ { - case lb ~ contents ~ rb => lb + contents + rb + def block: Parser[PString] = "{".p ~ standardExpression ~ "}".p ^^ { case lb ~ contents ~ rb => + lb + contents + rb } def operator: Parser[PString] = diff --git a/scex-core/src/main/scala/com/avsystem/scex/japi/DefaultJavaScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/japi/DefaultJavaScexCompiler.scala index 1aea11a0..971652b3 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/japi/DefaultJavaScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/japi/DefaultJavaScexCompiler.scala @@ -4,16 +4,14 @@ package japi import com.avsystem.scex.compiler._ import com.avsystem.scex.compiler.presentation.{CachingScexPresentationCompiler, ScexPresentationCompiler} -/** - * Created: 17-09-2013 - * Author: ghik - */ +/** Created: 17-09-2013 Author: ghik + */ class DefaultJavaScexCompiler(val settings: ScexSettings) extends ScexCompiler - with ScexPresentationCompiler - with ClassfileReusingScexCompiler - with TemplateOptimizingScexCompiler - with CachingScexCompiler - with CachingScexPresentationCompiler - with WeakReferenceWrappingScexCompiler - with JavaScexCompiler + with ScexPresentationCompiler + with ClassfileReusingScexCompiler + with TemplateOptimizingScexCompiler + with CachingScexCompiler + with CachingScexPresentationCompiler + with WeakReferenceWrappingScexCompiler + with JavaScexCompiler diff --git a/scex-core/src/main/scala/com/avsystem/scex/japi/JavaExpressionContext.scala b/scex-core/src/main/scala/com/avsystem/scex/japi/JavaExpressionContext.scala index c99e8910..052353e3 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/japi/JavaExpressionContext.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/japi/JavaExpressionContext.scala @@ -5,7 +5,7 @@ import com.avsystem.scex.{ExpressionContext, NoTag} abstract class JavaExpressionContext[R, V] extends ExpressionContext[R, V] { type VarTag[T] = NoTag - private type SuperSelf = ExpressionContext[R, V] {type VarTag[T] = NoTag} + private type SuperSelf = ExpressionContext[R, V] { type VarTag[T] = NoTag } def setTypedVariable[T](name: String, value: T): Unit = (this: SuperSelf).setTypedVariable(name, value)(NoTag) def getTypedVariable[T](name: String): T = (this: SuperSelf).getTypedVariable(name)(NoTag) diff --git a/scex-core/src/main/scala/com/avsystem/scex/japi/JavaScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/japi/JavaScexCompiler.scala index fe8f3dae..ce459b2e 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/japi/JavaScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/japi/JavaScexCompiler.scala @@ -17,18 +17,18 @@ trait JavaScexCompiler extends ScexCompiler with ScexPresentationCompiler { import com.avsystem.scex.util.CacheImplicits._ - private val typesCache = CacheBuilder.newBuilder.weakKeys - .build[Type, String](javaTypeAsScalaType _) + private val typesCache = CacheBuilder.newBuilder.weakKeys.build[Type, String](javaTypeAsScalaType _) - private val rootObjectClassCache = CacheBuilder.newBuilder.weakKeys - .build[TypeToken[_ <: ExpressionContext[_, _]], Class[_]](getRootObjectClass _) + private val rootObjectClassCache = + CacheBuilder.newBuilder.weakKeys.build[TypeToken[_ <: ExpressionContext[_, _]], Class[_]](getRootObjectClass _) private def getRootObjectClass(token: TypeToken[_ <: ExpressionContext[_, _]]): Class[_] = token.getSupertype(classOf[ExpressionContext[_, _]]).getType match { - case ParameterizedType(_, _, Array(rootObjectType, _)) => rootObjectType match { - case TypeAny | TypeAnyVal => null - case _ => TypeToken.of(rootObjectType).getRawType - } + case ParameterizedType(_, _, Array(rootObjectType, _)) => + rootObjectType match { + case TypeAny | TypeAnyVal => null + case _ => TypeToken.of(rootObjectType).getRawType + } case clazz if clazz == classOf[ExpressionContext[_, _]] => classOf[Object] } @@ -55,13 +55,23 @@ trait JavaScexCompiler extends ScexCompiler with ScexPresentationCompiler { val scalaContextType = typesCache.get(_contextTypeToken.getType) val scalaResultType = typesCache.get(_resultTypeToken.getType) val rootObjectClass = rootObjectClassCache.get(_contextTypeToken) - val variableTypes = _variableTypes.asScala.iterator.map { - case (key, value) => (key, typesCache.get(value.getType)) + val variableTypes = _variableTypes.asScala.iterator.map { case (key, value) => + (key, typesCache.get(value.getType)) }.toMap val (actualExpression, positionMapping) = preprocess(_expression, _template) - getCompiledExpression[C, T](ExpressionDef(_profile, _template, _setter, actualExpression, _header, - scalaContextType, scalaResultType, variableTypes)(_expression, positionMapping, rootObjectClass)) + getCompiledExpression[C, T]( + ExpressionDef( + _profile, + _template, + _setter, + actualExpression, + _header, + scalaContextType, + scalaResultType, + variableTypes, + )(_expression, positionMapping, rootObjectClass) + ) } def contextType[NC <: ExpressionContext[_, _]](contextTypeToken: TypeToken[NC]): ExpressionBuilder[NC, T] = fluent { @@ -150,11 +160,20 @@ trait JavaScexCompiler extends ScexCompiler with ScexPresentationCompiler { val scalaContextType = typesCache.get(_contextTypeToken.getType) val scalaResultType = typesCache.get(_resultTypeToken.getType) val rootObjectClass = rootObjectClassCache.get(_contextTypeToken) - val variableTypes = _variableTypes.asScala.iterator.map { - case (key, value) => (key, typesCache.get(value.getType)) + val variableTypes = _variableTypes.asScala.iterator.map { case (key, value) => + (key, typesCache.get(value.getType)) }.toMap - getCompleter(_profile, _template, _setter, _header, scalaContextType, rootObjectClass, scalaResultType, variableTypes) + getCompleter( + _profile, + _template, + _setter, + _header, + scalaContextType, + rootObjectClass, + scalaResultType, + variableTypes, + ) } def contextType(contextTypeToken: TypeToken[_ <: ExpressionContext[_, _]]): this.type = fluent { diff --git a/scex-core/src/main/scala/com/avsystem/scex/japi/ScalaTypeTokens.scala b/scex-core/src/main/scala/com/avsystem/scex/japi/ScalaTypeTokens.scala index ae45ffca..09ec448d 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/japi/ScalaTypeTokens.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/japi/ScalaTypeTokens.scala @@ -4,10 +4,8 @@ package japi import com.avsystem.scex.compiler.JavaTypeParsing import com.google.common.reflect.TypeToken -/** - * Created: 18-11-2013 - * Author: ghik - */ +/** Created: 18-11-2013 Author: ghik + */ object ScalaTypeTokens { def any = TypeToken.of(JavaTypeParsing.TypeAny).asInstanceOf[TypeToken[Any]] diff --git a/scex-core/src/main/scala/com/avsystem/scex/japi/XmlFriendlyJavaScexCompiler.scala b/scex-core/src/main/scala/com/avsystem/scex/japi/XmlFriendlyJavaScexCompiler.scala index e7f7f580..f832c1b7 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/japi/XmlFriendlyJavaScexCompiler.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/japi/XmlFriendlyJavaScexCompiler.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.compiler._ import com.avsystem.scex.compiler.presentation.{CachingScexPresentationCompiler, ScexPresentationCompiler} import com.avsystem.scex.compiler.xmlfriendly.XmlFriendlyScexCompiler -/** - * Created: 17-09-2013 - * Author: ghik - */ +/** Created: 17-09-2013 Author: ghik + */ class XmlFriendlyJavaScexCompiler(val settings: ScexSettings) extends ScexCompiler with ScexPresentationCompiler diff --git a/scex-core/src/main/scala/com/avsystem/scex/parsing/PString.scala b/scex-core/src/main/scala/com/avsystem/scex/parsing/PString.scala index aac597dc..e40d5df7 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/parsing/PString.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/parsing/PString.scala @@ -10,9 +10,7 @@ object Binding extends AbstractValueEnumCompanion[Binding] { final val Left, Right: Value = new Binding } -/** - * Created: 24-10-2013 - * Author: ghik +/** Created: 24-10-2013 Author: ghik */ final case class Modification(offset: Int, amount: Int, binding: Binding) @@ -54,8 +52,10 @@ final case class PString(result: String, beg: Int, end: Int, mods: Vector[Modifi } def replaceWith(replacement: String, binding: Binding): PString = - copy(result = replacement, mods = - Modification(beg, -result.length, binding) +: Modification(beg, replacement.length, binding) +: mods) + copy( + result = replacement, + mods = Modification(beg, -result.length, binding) +: Modification(beg, replacement.length, binding) +: mods, + ) def withResult(result: String): PString = copy(result = result) @@ -65,20 +65,26 @@ object PString { @tailrec private[scex] def computeMapping( mods: List[Modification], acc: List[(Int, ShiftInfo)], - racc: List[(Int, ShiftInfo)] + racc: List[(Int, ShiftInfo)], ): (SortedMap[Int, ShiftInfo], SortedMap[Int, ShiftInfo]) = (mods, acc, racc) match { - case (Modification(offset, amount, binding) :: tail, (prevOffset, prevInfo) :: accTail, (rprevOffset, rprevInfo) :: raccTail) => - val newAcc = if (offset == prevOffset) - (prevOffset, prevInfo.update(amount, binding)) :: accTail - else - (offset, ShiftInfo(prevInfo.totalShift, amount, binding)) :: acc + case ( + Modification(offset, amount, binding) :: tail, + (prevOffset, prevInfo) :: accTail, + (rprevOffset, rprevInfo) :: raccTail, + ) => + val newAcc = + if (offset == prevOffset) + (prevOffset, prevInfo.update(amount, binding)) :: accTail + else + (offset, ShiftInfo(prevInfo.totalShift, amount, binding)) :: acc val roffset = offset + (if (offset == prevOffset) prevInfo.totalPrevShift else prevInfo.totalShift) - val newRacc = if (roffset == rprevOffset) - (rprevOffset, rprevInfo.update(-amount, binding)) :: raccTail - else - (roffset, ShiftInfo(rprevInfo.totalShift, -amount, binding)) :: racc + val newRacc = + if (roffset == rprevOffset) + (rprevOffset, rprevInfo.update(-amount, binding)) :: raccTail + else + (roffset, ShiftInfo(rprevInfo.totalShift, -amount, binding)) :: racc computeMapping(tail, newAcc, newRacc) @@ -91,4 +97,4 @@ object PString { case tuple => throw new IllegalArgumentException(tuple.toString()) } -} \ No newline at end of file +} diff --git a/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionMapping.scala b/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionMapping.scala index 009dc8d9..907a2705 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionMapping.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionMapping.scala @@ -3,9 +3,7 @@ package com.avsystem.scex.parsing import scala.annotation.nowarn import scala.collection.immutable.SortedMap -/** - * Created: 24-10-2013 - * Author: ghik +/** Created: 24-10-2013 Author: ghik */ trait PositionMapping { def apply(pos: Int): Int @@ -18,7 +16,7 @@ trait PositionMapping { else ComposedPositionMapping(this, other) def andThen(other: PositionMapping): PositionMapping = - other compose this + other.compose(this) } final case class ShiftInfo(totalPrevShift: Int, addedLeft: Int, removedLeft: Int, addedRight: Int, removedRight: Int) { @@ -50,7 +48,7 @@ object ShiftInfo { class ShiftInfoPositionMapping( private val shiftMapping: SortedMap[Int, ShiftInfo], - private val reverseShiftMapping: SortedMap[Int, ShiftInfo] + private val reverseShiftMapping: SortedMap[Int, ShiftInfo], ) extends PositionMapping { @nowarn("msg=deprecated") diff --git a/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionTrackingParsers.scala b/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionTrackingParsers.scala index 517dd9ab..38b39dcd 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionTrackingParsers.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/parsing/PositionTrackingParsers.scala @@ -2,13 +2,11 @@ package com.avsystem.scex.parsing import scala.util.parsing.combinator.RegexParsers -/** - * Extensions for Scala parser combinators that allow to turn Parser[String] instances into Parser[PString] instances +/** Extensions for Scala parser combinators that allow to turn Parser[String] instances into Parser[PString] instances * that hold information about differences between original and transformed string that later allow to map cursor * positions between the two. * - * Created: 21-10-2013 - * Author: ghik + * Created: 21-10-2013 Author: ghik */ trait PositionTrackingParsers extends RegexParsers { @@ -20,7 +18,8 @@ trait PositionTrackingParsers extends RegexParsers { class ReplacingParser(parser: Parser[String], replacement: String, binding: Binding) extends Parser[PString] { def apply(in: Input): ParseResult[PString] = parser(in).map { str => - val mods = Vector(Modification(in.offset, -str.length, binding), Modification(in.offset, replacement.length, binding)) + val mods = + Vector(Modification(in.offset, -str.length, binding), Modification(in.offset, replacement.length, binding)) PString(replacement, in.offset, in.offset + str.length, mods) } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/parsing/ScalaParsingCommons.scala b/scex-core/src/main/scala/com/avsystem/scex/parsing/ScalaParsingCommons.scala index 0405958d..be9cad75 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/parsing/ScalaParsingCommons.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/parsing/ScalaParsingCommons.scala @@ -3,11 +3,8 @@ package com.avsystem.scex.parsing import scala.reflect.internal.Chars import scala.util.parsing.combinator.RegexParsers - -/** - * Created: 30-10-2014 - * Author: ghik - */ +/** Created: 30-10-2014 Author: ghik + */ trait ScalaParsingCommons extends RegexParsers { override def skipWhitespace = false @@ -26,9 +23,10 @@ trait ScalaParsingCommons extends RegexParsers { implicit val stringStringParseable: StringParseable[String] = new StringParseable[String] implicit val elemStringParseable: StringParseable[Char] = new StringParseable[Elem] - implicit def optionStringParseable[T: StringParseable]: StringParseable[Option[T]] = new StringParseable[Option[T]] { - override def toString(t: Option[T]): String = t.map(implicitly[StringParseable[T]].toString).getOrElse("") - } + implicit def optionStringParseable[T: StringParseable]: StringParseable[Option[T]] = + new StringParseable[Option[T]] { + override def toString(t: Option[T]): String = t.map(implicitly[StringParseable[T]].toString).getOrElse("") + } } protected implicit class StringParseableParserOps[L: StringParseable](parser: Parser[L]) { @@ -95,13 +93,13 @@ trait ScalaParsingCommons extends RegexParsers { """([^"\p{Cntrl}\\])+""".r val quotedInterpolationChars: Parser[String] = - repjoin( """([^"\p{Cntrl}\$])+|\$\$""".r) + repjoin("""([^"\p{Cntrl}\$])+|\$\$""".r) val multilineChars: Parser[String] = """([^"\p{Cntrl}])+|"{1,2}(?!")""".r val multilineInterpolationChars: Parser[String] = - repjoin( """([^"\p{Cntrl}\$])+|"{1,2}(?!")|\$\$|\s+""".r) + repjoin("""([^"\p{Cntrl}\$])+|"{1,2}(?!")|\$\$|\s+""".r) val interpolationArg: Parser[String] = "$" ~~ (plainIdent | block) @@ -125,7 +123,8 @@ trait ScalaParsingCommons extends RegexParsers { "\"\"\"" ~~ repjoin(multilineChars) ~~ multilineEnd val multilineInterpolation: Parser[String] = - ident ~~ "\"\"\"" ~~ repjoin(multilineInterpolationChars ~~ interpolationArg) ~~ multilineInterpolationChars ~~ multilineEnd + ident ~~ "\"\"\"" ~~ repjoin(multilineInterpolationChars ~~ interpolationArg) ~~ multilineInterpolationChars ~~ + multilineEnd val whitespace: Parser[String] = """\s+""".r @@ -140,8 +139,10 @@ trait ScalaParsingCommons extends RegexParsers { "(" ~~ expr ~~ ")" def expr: Parser[String] = - repjoin(whitespace | block | brackets | parens | delim | multilineInterpolation | multilineString | - stringInterpolation | stringLiteral | charLiteral | symbolLiteral | number | delim | ident | btident | operator) + repjoin( + whitespace | block | brackets | parens | delim | multilineInterpolation | multilineString | stringInterpolation | + stringLiteral | charLiteral | symbolLiteral | number | delim | ident | btident | operator + ) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/parsing/TemplateParser.scala b/scex-core/src/main/scala/com/avsystem/scex/parsing/TemplateParser.scala index 022cde96..9c6a5a98 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/parsing/TemplateParser.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/parsing/TemplateParser.scala @@ -1,16 +1,14 @@ package com.avsystem.scex.parsing -/** - * Created: 03-11-2014 - * Author: ghik - */ +/** Created: 03-11-2014 Author: ghik + */ object TemplateParser extends ScalaParsingCommons with PositionTrackingParsers { private val part = multilineInterpolationChars ^^ (_.replace("$$", "$")) private val arg = new ParserWithPos(interpolationArg) - private val templateParser = rep(part ~ arg) ~ part ^^ { - case pairs ~ lastPart => (pairs.map(_._1) :+ lastPart, pairs.map(_._2)) + private val templateParser = rep(part ~ arg) ~ part ^^ { case pairs ~ lastPart => + (pairs.map(_._1) :+ lastPart, pairs.map(_._2)) } def parseTemplate(expr: String): ParseResult[(List[String], List[PString])] = diff --git a/scex-core/src/main/scala/com/avsystem/scex/presentation/Attributes.scala b/scex-core/src/main/scala/com/avsystem/scex/presentation/Attributes.scala index 16088878..b878947a 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/presentation/Attributes.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/presentation/Attributes.scala @@ -1,18 +1,17 @@ package com.avsystem.scex.presentation -/** - * Author: ghik - * Created: 11/17/14. - */ +/** Author: ghik Created: 11/17/14. + */ final class Attributes( val paramNames: Option[List[String]], - val documentation: Option[String]) { + val documentation: Option[String], +) { def orElse(attrs: => Attributes): Attributes = { lazy val otherAttrs = attrs new Attributes( paramNames orElse otherAttrs.paramNames, - documentation orElse otherAttrs.documentation + documentation orElse otherAttrs.documentation, ) } diff --git a/scex-core/src/main/scala/com/avsystem/scex/presentation/MathAttributes.scala b/scex-core/src/main/scala/com/avsystem/scex/presentation/MathAttributes.scala index 7ac758e5..66ec5250 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/presentation/MathAttributes.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/presentation/MathAttributes.scala @@ -6,7 +6,9 @@ import com.avsystem.scex.symboldsl.SymbolInfo object MathAttributes { final val scalaMathAttributes: List[SymbolInfo[Attributes]] = attributes { on { m: math.`package`.type => - m.IEEEremainder _ --> Attributes(documentation = "Returns the remainder resulting from the division of a specified number `x` by another specified number `y`.") + m.IEEEremainder _ --> Attributes(documentation = + "Returns the remainder resulting from the division of a specified number `x` by another specified number `y`." + ) m.abs(_: Double) --> Attributes(documentation = "Returns absolute value of the `x` argument.") m.abs(_: Float) --> Attributes(documentation = "Returns absolute value of the `x` argument.") @@ -20,14 +22,18 @@ object MathAttributes { m.asin _ --> Attributes(documentation = "Returns the arc sine of the `x` argument.") m.atan _ --> Attributes(documentation = "Returns the arc tangent of the `x` argument.") - m.atan2 _ --> Attributes(documentation = "Returns the rectangular coordinates (x, y) converted to polar (r, theta).") + m.atan2 _ --> + Attributes(documentation = "Returns the rectangular coordinates (x, y) converted to polar (r, theta).") m.cbrt _ --> Attributes(documentation = "Returns the cube root of the `x` argument.") - m.ceil _ --> Attributes(documentation = "Returns the smallest double value that is greater than or equal to the `x` argument and is equal to a mathematical integer.") + m.ceil _ --> + Attributes(documentation = "Returns the smallest double value that is greater than or equal to the `x` argument and is equal to a mathematical integer.") - m.copySign(_: Double, _: Double) --> Attributes(documentation = "Returns the first argument `magnitude` with the sign of the second argument `sign`.") - m.copySign(_: Float, _: Float) --> Attributes(documentation = "Returns the first argument `magnitude` with the sign of the second argument `sign`.") + m.copySign(_: Double, _: Double) --> + Attributes(documentation = "Returns the first argument `magnitude` with the sign of the second argument `sign`.") + m.copySign(_: Float, _: Float) --> + Attributes(documentation = "Returns the first argument `magnitude` with the sign of the second argument `sign`.") m.cos _ --> Attributes(documentation = "Returns the cosine of the `x` argument.") m.cosh _ --> Attributes(documentation = "Returns the hyperbolic cosine of the `x` argument.") @@ -36,18 +42,34 @@ object MathAttributes { m.decrementExact(_: Long) --> Attributes(documentation = "Returns the `x` argument decremented by one.") m.exp _ --> Attributes(documentation = "Returns the Euler's number raised to the power of the `x` argument.") - m.expm1 _ --> Attributes(documentation = "Returns `exp(x) - 1`, the Euler's number raised to the power of the `x` argument minus one.") - - m.floor _ --> Attributes(documentation = "Returns the largest double value less than or equal to the `x` argument.") - m.floorDiv(_: Int, _: Int) --> Attributes(documentation = "Returns the largest integer value less than or equal to the algebraic quotient, " + "where `x` is the dividend and `y` is the divisor.") - m.floorDiv(_: Long, _: Long) --> Attributes(documentation = "Returns the largest long value less than or equal to the algebraic quotient, " + "where `x` is the dividend and `y` is the divisor.") - m.floorMod(_: Int, _: Int) --> Attributes(documentation = "Returns the floor modulus of the provided arguments, " + "where `x` is the dividend and `y` is the divisor.") - m.floorMod(_: Long, _: Long) --> Attributes(documentation = "Returns the floor modulus of the provided arguments, " + "where `x` is the dividend and `y` is the divisor.") - - m.getExponent(_: Double) --> Attributes(documentation = "Returns the unbiased exponent used in the representation of the `d` argument.") - m.getExponent(_: Float) --> Attributes(documentation = "Returns the unbiased exponent used in the representation of the `f` argument.") - - m.hypot _ --> Attributes(documentation = "Returns the square root of the sum of the squares of both `x` and `y` arguments without intermediate underflow or overflow.") + m.expm1 _ --> Attributes(documentation = + "Returns `exp(x) - 1`, the Euler's number raised to the power of the `x` argument minus one." + ) + + m.floor _ --> + Attributes(documentation = "Returns the largest double value less than or equal to the `x` argument.") + m.floorDiv(_: Int, _: Int) --> Attributes(documentation = + "Returns the largest integer value less than or equal to the algebraic quotient, " + + "where `x` is the dividend and `y` is the divisor." + ) + m.floorDiv(_: Long, _: Long) --> Attributes(documentation = + "Returns the largest long value less than or equal to the algebraic quotient, " + + "where `x` is the dividend and `y` is the divisor." + ) + m.floorMod(_: Int, _: Int) --> Attributes(documentation = + "Returns the floor modulus of the provided arguments, " + "where `x` is the dividend and `y` is the divisor." + ) + m.floorMod(_: Long, _: Long) --> Attributes(documentation = + "Returns the floor modulus of the provided arguments, " + "where `x` is the dividend and `y` is the divisor." + ) + + m.getExponent(_: Double) --> + Attributes(documentation = "Returns the unbiased exponent used in the representation of the `d` argument.") + m.getExponent(_: Float) --> + Attributes(documentation = "Returns the unbiased exponent used in the representation of the `f` argument.") + + m.hypot _ --> + Attributes(documentation = "Returns the square root of the sum of the squares of both `x` and `y` arguments without intermediate underflow or overflow.") m.incrementExact(_: Int) --> Attributes(documentation = "Returns the `x` argument incremented by one.") m.incrementExact(_: Long) --> Attributes(documentation = "Returns the `x` argument incremented by one.") @@ -56,39 +78,64 @@ object MathAttributes { m.log10 _ --> Attributes(documentation = "Returns base 10 natural logarithm of the `x` argument.") m.log1p _ --> Attributes(documentation = "Returns the natural logarithm of the sum of the `x` argument and 1") - m.max(_: Double, _: Double) --> Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") - m.max(_: Float, _: Float) --> Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") + m.max(_: Double, _: Double) --> + Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") + m.max(_: Float, _: Float) --> + Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") m.max(_: Int, _: Int) --> Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") - m.max(_: Long, _: Long) --> Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") + m.max(_: Long, _: Long) --> + Attributes(documentation = "Returns the greater of the provided `x` and `y` arguments.") - m.min(_: Double, _: Double) --> Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") - m.min(_: Float, _: Float) --> Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") + m.min(_: Double, _: Double) --> + Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") + m.min(_: Float, _: Float) --> + Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") m.min(_: Int, _: Int) --> Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") m.min(_: Long, _: Long) --> Attributes(documentation = "Returns the lesser of the provided `x` and `y` arguments.") m.multiplyExact(_: Int, _: Int) --> Attributes(documentation = "Returns the product of the `x` and `y` arguments.") - m.multiplyExact(_: Long, _: Long) --> Attributes(documentation = "Returns the product of the `x` and `y` arguments.") + m.multiplyExact(_: Long, _: Long) --> + Attributes(documentation = "Returns the product of the `x` and `y` arguments.") m.negateExact(_: Int) --> Attributes(documentation = "Returns negation of the provided `x` argument.") m.negateExact(_: Long) --> Attributes(documentation = "Returns negation of the provided `x` argument.") - m.nextAfter(_: Double, _: Double) --> Attributes(documentation = "Returns the floating-point number adjacent to the `start` argument in the direction of the `direction` argument.") - m.nextAfter(_: Float, _: Double) --> Attributes(documentation = "Returns the floating-point number adjacent to the `start` argument in the direction of the `direction` argument.") - m.nextDown(_: Double) --> Attributes(documentation = "Returns the floating-point value adjacent to the `d` argument in the direction of negative infinity.") - m.nextDown(_: Float) --> Attributes(documentation = "Returns the floating-point value adjacent to the `f` argument in the direction of negative infinity.") - m.nextUp(_: Double) --> Attributes(documentation = "Returns the floating-point value adjacent to the `d` argument in the direction of positive infinity.") - m.nextUp(_: Float) --> Attributes(documentation = "Returns the floating-point value adjacent to the `f` argument in the direction of positive infinity.") - - m.pow(_: Double, _: Double) --> Attributes(documentation = "Returns the value of the `x` argument raised to the power of the the `y` argument. ") - - m.rint _ --> Attributes(documentation = "Returns the closest floating point value that is equal to a mathematical integer for the `x` argument.") + m.nextAfter(_: Double, _: Double) --> + Attributes(documentation = "Returns the floating-point number adjacent to the `start` argument in the direction of the `direction` argument.") + m.nextAfter(_: Float, _: Double) --> + Attributes(documentation = "Returns the floating-point number adjacent to the `start` argument in the direction of the `direction` argument.") + m.nextDown(_: Double) --> Attributes(documentation = + "Returns the floating-point value adjacent to the `d` argument in the direction of negative infinity." + ) + m.nextDown(_: Float) --> Attributes(documentation = + "Returns the floating-point value adjacent to the `f` argument in the direction of negative infinity." + ) + m.nextUp(_: Double) --> Attributes(documentation = + "Returns the floating-point value adjacent to the `d` argument in the direction of positive infinity." + ) + m.nextUp(_: Float) --> Attributes(documentation = + "Returns the floating-point value adjacent to the `f` argument in the direction of positive infinity." + ) + + m.pow(_: Double, _: Double) --> + Attributes(documentation = "Returns the value of the `x` argument raised to the power of the the `y` argument. ") + + m.rint _ --> Attributes(documentation = + "Returns the closest floating point value that is equal to a mathematical integer for the `x` argument." + ) m.round(_: Double) --> Attributes(documentation = "Returns the `x` argument rounded to the closest integer value.") m.round(_: Float) --> Attributes(documentation = "Returns the `x` argument rounded to the closest integer value.") m.round(_: Long) --> Attributes(documentation = "Returns the `x` argument rounded to the closest integer value.") - m.scalb(_: Double, _: Int) --> Attributes(documentation = "Returns `d` times 2 to the power of `scaleFactor` " + "rounded as if performed by a single correctly rounded floating-point multiply.") - m.scalb(_: Float, _: Int) --> Attributes(documentation = "Returns `f` times 2 to the power of `scaleFactor` " + "rounded as if performed by a single correctly rounded floating-point multiply.") + m.scalb(_: Double, _: Int) --> Attributes(documentation = + "Returns `d` times 2 to the power of `scaleFactor` " + + "rounded as if performed by a single correctly rounded floating-point multiply." + ) + m.scalb(_: Float, _: Int) --> Attributes(documentation = + "Returns `f` times 2 to the power of `scaleFactor` " + + "rounded as if performed by a single correctly rounded floating-point multiply." + ) m.signum(_: Double) --> Attributes(documentation = "Returns the signum function of the `x` argument.") m.signum(_: Float) --> Attributes(documentation = "Returns the signum function of the `x` argument.") @@ -100,16 +147,23 @@ object MathAttributes { m.sqrt _ --> Attributes(documentation = "Returns the square root of the `x` argument.") - m.subtractExact(_: Int, _: Int) --> Attributes(documentation = "Returns the difference of the `x` and `y` arguments.") - m.subtractExact(_: Long, _: Long) --> Attributes(documentation = "Returns the difference of the `x` and `y` arguments.") + m.subtractExact(_: Int, _: Int) --> + Attributes(documentation = "Returns the difference of the `x` and `y` arguments.") + m.subtractExact(_: Long, _: Long) --> + Attributes(documentation = "Returns the difference of the `x` and `y` arguments.") m.tan _ --> Attributes(documentation = "Returns the tangent of the `x` argument.") m.tanh _ --> Attributes(documentation = "Returns the hyperbolic tangent of the `x` argument.") - m.toDegrees _ --> Attributes(documentation = "Returns an angle measured in radians `x` converted to an approximately equivalent angle measured in degrees.") - m.toRadians _ --> Attributes(documentation = "Returns an angle measured in degrees `x` converted to an approximately equivalent angle measured in radians.") + m.toDegrees _ --> Attributes(documentation = + "Returns an angle measured in radians `x` converted to an approximately equivalent angle measured in degrees." + ) + m.toRadians _ --> Attributes(documentation = + "Returns an angle measured in degrees `x` converted to an approximately equivalent angle measured in radians." + ) - m.ulp(_: Double) --> Attributes(documentation = "Returns the size of a unit in the last place of the `x` argument.") + m.ulp(_: Double) --> + Attributes(documentation = "Returns the size of a unit in the last place of the `x` argument.") m.ulp(_: Float) --> Attributes(documentation = "Returns the size of a unit in the last place of the `x` argument.") } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/presentation/SymbolAttributes.scala b/scex-core/src/main/scala/com/avsystem/scex/presentation/SymbolAttributes.scala index 03a9d6c9..b67fef2b 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/presentation/SymbolAttributes.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/presentation/SymbolAttributes.scala @@ -4,10 +4,8 @@ import com.avsystem.scex.symboldsl.{SymbolDsl, SymbolDslMacros, SymbolInfo, Symb import scala.language.experimental.macros -/** - * Author: ghik - * Created: 11/17/14. - */ +/** Author: ghik Created: 11/17/14. + */ class SymbolAttributes(val infoList: List[SymbolInfo[Attributes]]) extends SymbolInfoList[Attributes] { def combine(other: SymbolAttributes) = SymbolAttributes(infoList ++ other.infoList) diff --git a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolDsl.scala b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolDsl.scala index 043258f2..6fd36ca8 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolDsl.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolDsl.scala @@ -1,13 +1,11 @@ package com.avsystem.scex.symboldsl -import scala.annotation.{StaticAnnotation, compileTimeOnly} +import scala.annotation.{compileTimeOnly, StaticAnnotation} import scala.language.experimental.macros import scala.language.{dynamics, implicitConversions} -/** - * Author: ghik - * Created: 11/14/14. - */ +/** Author: ghik Created: 11/14/14. + */ trait SymbolDsl { type Payload @@ -17,42 +15,33 @@ trait SymbolDsl { @compileTimeOnly("You cannot use this outside of symbol DSL") implicit def toDirectWildcardSelector(any: Any): DirectWildcardSelector = stub - /** - * Starts a block that allows or denies calling some methods on instances of some type. This is expressed using - * lambda expression like this: - * - *
-   * on { s: String =>
-   *   s.compareTo _
-   *   s.charAt _
-   *   s.length
-   * }
-   * @param expr
-   * @tparam A
-   * @return
-   */
+  /** Starts a block that allows or denies calling some methods on instances of some type. This is expressed using
+    * lambda expression like this:
+    *
+    * 
 on { s: String =>   s.compareTo _   s.charAt _   s.length }
+    * @param expr
+    * @tparam A
+    * @return
+    */
   def on[A](expr: A => Any): A => Any = macro SymbolInfoParser.on_impl[A]
 
-  /**
-   * Starts "wildcard" notation to allow or deny calling multiple Java static methods, with single DSL statement.
-   * For example:
-   *
-   * 
-   * allStatic[String].membersNamed.valueOf
-   * 
- * - * @tparam A - * @return - */ + /** Starts "wildcard" notation to allow or deny calling multiple Java static methods, with single DSL statement. For + * example: + * + *
 allStatic[String].membersNamed.valueOf 
+ * + * @tparam A + * @return + */ @compileTimeOnly("You cannot use this outside of symbol DSL") def allStatic[A]: MemberSubsets = stub trait AttachedPayload trait AttachPayload { - /** - * Attaches some payload to specified member or members on given type. - */ + + /** Attaches some payload to specified member or members on given type. + */ @compileTimeOnly("You cannot use this outside of symbol DSL") def -->(payload: Payload): AttachedPayload } @@ -64,18 +53,14 @@ trait SymbolDsl { trait CompleteWildcardSelector extends Any trait WildcardSelector extends Any { - /** - * Starts "wildcard" notation to allow or deny calling multiple methods on some type, - * in single DSL statement. Example: - * - *
-     * on { s: String =>
-     *   s.all.declared.methods
-     * }
-     * 
- * - * @return - */ + + /** Starts "wildcard" notation to allow or deny calling multiple methods on some type, in single DSL statement. + * Example: + * + *
 on { s: String =>   s.all.declared.methods } 
+ * + * @return + */ def all: ScopeSpecifiers with MemberSubsets } @@ -84,118 +69,98 @@ trait SymbolDsl { def as[S]: S - /** - * Starts "wildcard" notation to allow or deny calling multiple methods available through implicit conversion - * on some type, in single DSL statement. Example: - * - *
-     * on { i: Int =>
-     *   i.implicitlyAs[RichInt].all.declared.methods
-     * }
-     * 
- * - * Implicit conversion used in Symbol DSL must be globally visible (e.g. method in non-nested Scala object) - * - * @tparam A - * @return - */ + /** Starts "wildcard" notation to allow or deny calling multiple methods available through implicit conversion on + * some type, in single DSL statement. Example: + * + *
 on { i: Int =>   i.implicitlyAs[RichInt].all.declared.methods } 
+ * + * Implicit conversion used in Symbol DSL must be globally visible (e.g. method in non-nested Scala object) + * + * @tparam A + * @return + */ def implicitlyAs[A]: WildcardSelector def constructorWithSignature(signature: String): CompleteWildcardSelector } trait ScopeSpecifiers extends Any { - /** - * Filters out methods specified by "wildcard" notation leaving only these declared in class - * that represents given type. - * @return - */ + + /** Filters out methods specified by "wildcard" notation leaving only these declared in class that represents given + * type. + * @return + */ def declared: ScalaMemberSubsets - /** - * Filters out methods specified by "wildcard" notation leaving only these introduced in class - * that represents given type, where 'introduced' means declared and not overriding anything. - * @return - */ + /** Filters out methods specified by "wildcard" notation leaving only these introduced in class that represents + * given type, where 'introduced' means declared and not overriding anything. + * @return + */ def introduced: ScalaMemberSubsets } trait MemberSubsets extends Any { - /** - * Allows or denies calling all methods (not constructors) available for given type, on this type, except - * for members from `Any`/`AnyVal`/`AnyRef`. - * @return - */ + + /** Allows or denies calling all methods (not constructors) available for given type, on this type, except for + * members from `Any`/`AnyVal`/`AnyRef`. + * @return + */ def members: CompleteWildcardSelector - /** - * Allows or denies calling all overloaded variants of method with given name available for given type, on this type. - * Uses Dynamic notation, for example: - * - *
-     * on { s: String =>
-     *   s.all.membersNamed.getBytes
-     * }
-     * 
- * - * @return - */ + /** Allows or denies calling all overloaded variants of method with given name available for given type, on this + * type. Uses Dynamic notation, for example: + * + *
 on { s: String =>   s.all.membersNamed.getBytes } 
+ * + * @return + */ def membersNamed: MembersNamed - /** - * Allows or denies calling all methods with given names available for given type, on this type. - * For example: - * - *
-     * on { s: String =>
-     *   s.all.membersNamed("getBytes")
-     * }
-     * 
- * - * @return - */ + /** Allows or denies calling all methods with given names available for given type, on this type. For example: + * + *
 on { s: String =>   s.all.membersNamed("getBytes") } 
+ * + * @return + */ def membersNamed(names: String*): CompleteWildcardSelector - /** - * Allows or denies calling all JavaBean getters available for given type, on this type. - * JavaBean getter is defined as a method taking no parameters or type parameters, - * with name starting with get (or is if it returns boolean or java.lang.Boolean) - * followed by capitalized name of bean property. - * - * @return - */ + /** Allows or denies calling all JavaBean getters available for given type, on this type. JavaBean getter is defined + * as a method taking no parameters or type parameters, with name starting with get (or is if it + * returns boolean or java.lang.Boolean) followed by capitalized name of bean property. + * + * @return + */ def beanGetters: CompleteWildcardSelector - /** - * Allows or denies calling all JavaBean setters available for given type, on this type. - * JavaBean setter is defined as a method returning void, taking single parameter and no type parameters, - * with name starting with set followed by capitalized name of bean property. - * - * @return - */ + /** Allows or denies calling all JavaBean setters available for given type, on this type. JavaBean setter is defined + * as a method returning void, taking single parameter and no type parameters, with name starting with + * set followed by capitalized name of bean property. + * + * @return + */ def beanSetters: CompleteWildcardSelector } trait ScalaMemberSubsets extends MemberSubsets { - /** - * Allows or denies calling getters for Scala vals or vars available for given type, on this type. - * @return - */ + + /** Allows or denies calling getters for Scala vals or vars available for given type, on this + * type. + * @return + */ def scalaGetters: CompleteWildcardSelector - /** - * Allows or denies calling setters for Scala vars available for given type, on this type. - * @return - */ + /** Allows or denies calling setters for Scala vars available for given type, on this type. + * @return + */ def scalaSetters: CompleteWildcardSelector } trait DirectMemberSubsets extends ScalaMemberSubsets { - /** - * Allows or denies creating new instances of given type (or subtypes if they still correspond to the same class) - * using any available constructor. - * @return - */ + + /** Allows or denies creating new instances of given type (or subtypes if they still correspond to the same class) + * using any available constructor. + * @return + */ def constructors: CompleteWildcardSelector } @@ -203,38 +168,18 @@ trait SymbolDsl { def selectDynamic(name: String): CompleteWildcardSelector = stub } - /** - * Type annotation that serves as an alternative way of expressing existential types (types with wildcards) with - * higher bounds in the symbol DSL. - *

- * For example, imagine you want to allow invoking insert method on all lists of type - * java.util.List[_ <: Number]. Unfortunately, the following will NOT work: - *
-   * allow {
-   * on { l: java.util.List[_ <: Number] =>
-   * l.insert _  // won't typecheck
-   * }
-   * }
-   * 
- *

- * Scala typechecker will report an error on l.insert _ because this method cannot be called - * when the element type of the list is unknown. - *

- * To overcome this limitation, you can use alternative syntax to express the same: - *
-   * allow {
-   * on { l: java.util.List[Number@plus] =>
-   * l.insert _
-   * }
-   * }
-   * 
- */ + /** Type annotation that serves as an alternative way of expressing existential types (types with wildcards) with + * higher bounds in the symbol DSL.

For example, imagine you want to allow invoking insert method on + * all lists of type java.util.List[_ <: Number]. Unfortunately, the following will NOT work:
 allow {
+    * on { l: java.util.List[_ <: Number] => l.insert _ // won't typecheck } } 

Scala typechecker will report + * an error on l.insert _ because this method cannot be called when the element type of the list is unknown. + *

To overcome this limitation, you can use alternative syntax to express the same:
 allow { on { l:
+    * java.util.List[Number@plus] => l.insert _ } } 
+ */ class plus extends StaticAnnotation - /** - * Analogous to [[plus]], - * but used to express wildcards with lower bounds, e.g. java.lang.List[_ >: String] - */ + /** Analogous to [[plus]], but used to express wildcards with lower bounds, e.g. java.lang.List[_ >: String] + */ class minus extends StaticAnnotation } diff --git a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfo.scala b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfo.scala index 806136eb..cf7ccf49 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfo.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfo.scala @@ -1,8 +1,6 @@ package com.avsystem.scex package symboldsl -/** - * Author: ghik - * Created: 11/14/14. - */ +/** Author: ghik Created: 11/14/14. + */ final case class SymbolInfo[T](typeInfo: TypeInfo, memberSignature: String, implicitConv: Option[String], payload: T) diff --git a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoList.scala b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoList.scala index 7554086b..d81da9f2 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoList.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoList.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.util.MacroUtils import scala.collection.immutable.{SortedSet, TreeSet} import scala.reflect.api.Universe -/** - * Author: ghik - * Created: 11/17/14. - */ +/** Author: ghik Created: 11/17/14. + */ trait SymbolInfoList[T] { case class InfoWithIndex(info: SymbolInfo[T], index: Int) @@ -17,13 +15,18 @@ trait SymbolInfoList[T] { lazy val size = infoList.length lazy val bySignaturesMap: Map[String, List[InfoWithIndex]] = - infoList.zipWithIndex.map { - case (info, index) => InfoWithIndex(info, index) - }.groupBy(_.info.memberSignature).map { - case (signature, infos) => (signature, infos.sortBy(_.index)) - }.withDefaultValue(Nil) + infoList.zipWithIndex + .map { case (info, index) => + InfoWithIndex(info, index) + } + .groupBy(_.info.memberSignature) + .map { case (signature, infos) => + (signature, infos.sortBy(_.index)) + } + .withDefaultValue(Nil) - def matchingInfos(u: Universe)(prefixTpe: u.Type, symbol: u.Symbol, implicitConv: Option[u.Tree]): List[InfoWithIndex] = { + def matchingInfos(u: Universe)(prefixTpe: u.Type, symbol: u.Symbol, implicitConv: Option[u.Tree]) + : List[InfoWithIndex] = { val macroUtils = MacroUtils(u) import macroUtils._ @@ -34,9 +37,8 @@ trait SymbolInfoList[T] { signatures.flatMap { signature => bySignaturesMap(signature).filter { case InfoWithIndex(symbolInfo, _) => - signature == symbolInfo.memberSignature && - prefixTpe <:< symbolInfo.typeInfo.typeIn(u) && - implicitConvPath == symbolInfo.implicitConv + signature == symbolInfo.memberSignature && prefixTpe <:< symbolInfo.typeInfo.typeIn(u) && + implicitConvPath == symbolInfo.implicitConv } } } diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/CacheImplicits.scala b/scex-core/src/main/scala/com/avsystem/scex/util/CacheImplicits.scala index 2780d55c..f6be207b 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/CacheImplicits.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/CacheImplicits.scala @@ -5,7 +5,6 @@ import com.google.common.cache.{CacheLoader, RemovalListener, RemovalNotificatio import scala.language.implicitConversions - object CacheImplicits { implicit def funToCacheLoader[K, V](fun: K => V): CacheLoader[K, V] = new CacheLoader[K, V] { diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/CommonUtils.scala b/scex-core/src/main/scala/com/avsystem/scex/util/CommonUtils.scala index d843509c..c8f4848b 100755 --- a/scex-core/src/main/scala/com/avsystem/scex/util/CommonUtils.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/CommonUtils.scala @@ -9,18 +9,49 @@ import scala.annotation.nowarn import scala.collection.mutable import scala.reflect.ClassTag - -/** - * Created with IntelliJ IDEA. - * User: ghik - * Date: 08.01.13 - * Time: 21:03 - */ +/** Created with IntelliJ IDEA. User: ghik Date: 08.01.13 Time: 21:03 + */ object CommonUtils { final val ScalaKeywords = Set( - "abstract", "case", "catch", "class", "def", "do", "else", "extends", "false", "final", "finally", "for", "forSome", - "if", "implicit", "import", "lazy", "match", "new", "null", "object", "override", "package", "private", "protected", - "return", "sealed", "super", "this", "throw", "trait", "try", "true", "type", "val", "var", "while", "with", "yield" + "abstract", + "case", + "catch", + "class", + "def", + "do", + "else", + "extends", + "false", + "final", + "finally", + "for", + "forSome", + "if", + "implicit", + "import", + "lazy", + "match", + "new", + "null", + "object", + "override", + "package", + "private", + "protected", + "return", + "sealed", + "super", + "this", + "throw", + "trait", + "try", + "true", + "type", + "val", + "var", + "while", + "with", + "yield", ) final val BeanGetterNamePattern = "get(([A-Z][a-z0-9_]*)+)".r @@ -83,7 +114,8 @@ object CommonUtils { directSuperclasses(clazz).flatMap { superClass => try { Some(superClass.getMethod(method.getName, method.getParameterTypes: _*)) - .filter(m => Modifier.isPublic(m.getModifiers)).map(_.getDeclaringClass) + .filter(m => Modifier.isPublic(m.getModifiers)) + .map(_.getDeclaringClass) } catch { case _: NoSuchMethodException => None } diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/DynamicAdapters.scala b/scex-core/src/main/scala/com/avsystem/scex/util/DynamicAdapters.scala index 8512c7b4..b282d3d8 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/DynamicAdapters.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/DynamicAdapters.scala @@ -7,10 +7,8 @@ import scala.collection.mutable import com.avsystem.commons.jiop.JavaInterop._ import scala.language.dynamics - -/** - * Interfaces and utilities to allow Java implementations of `scala.Dynamic` - */ +/** Interfaces and utilities to allow Java implementations of `scala.Dynamic` + */ object DynamicAdapters { trait SelectAdapter[+R] extends Dynamic { @@ -46,53 +44,44 @@ object DynamicAdapters { } trait ApplyVarargsAdapter[-AV, +R] extends Dynamic { - /** - * Note: you can use `DynamicAdapters#varargsAsJavaList` to convert - * args to `java.util.List`. - */ + + /** Note: you can use `DynamicAdapters#varargsAsJavaList` to convert args to `java.util.List`. + */ def applyDynamic(method: String)(args: AV*): R } - /** - * Converts Scala-style varargs (a `scala.collection.Seq`) into an unmodifiable `java.util.List`. - */ + /** Converts Scala-style varargs (a `scala.collection.Seq`) into an unmodifiable `java.util.List`. + */ def varargsAsJavaList[AV](args: AV*) = args.asJava trait ApplyNamedAdapter[-AV, +R] extends Dynamic { - /** - * Note: you can use `DynamicAdapters#namedArgsAsJavaMap` and - * `DynamicAdapters#unnamedArgsAsJavaList` to extract named and unnamed - * parameters from args as `java.util.Map` and `java.util.List` - */ + + /** Note: you can use `DynamicAdapters#namedArgsAsJavaMap` and `DynamicAdapters#unnamedArgsAsJavaList` to extract + * named and unnamed parameters from args as `java.util.Map` and `java.util.List` + */ def applyDynamicNamed(method: String)(args: (String, AV)*): R } - /** - * Extracts named arguments from named argument list and returns it - * as unmodifiable `java.util.Map` with preserved order. - * - * E.g. for invocation obj.someDynamicMethod(a = 1, 2, b = 3, 4), returned map will be - * {a=1,b=3} - */ - def namedArgsAsJavaMap[AV](args: (String, AV)*) = Collections.unmodifiableMap[String, AV]( - mutable.LinkedHashMap(args.filter(_._1.nonEmpty): _*).asJava) - - /** - * Extracts unnamed argument values from named argument list and returns it as unmodifiable - * `java.util.List`. - * - * E.g. for invocation obj.someDynamicMethod(a = 1, 2, b = 3, 4), returned list will be - * [2,4] - */ + /** Extracts named arguments from named argument list and returns it as unmodifiable `java.util.Map` with preserved + * order. + * + * E.g. for invocation obj.someDynamicMethod(a = 1, 2, b = 3, 4), returned map will be {a=1,b=3} + */ + def namedArgsAsJavaMap[AV](args: (String, AV)*) = + Collections.unmodifiableMap[String, AV](mutable.LinkedHashMap(args.filter(_._1.nonEmpty): _*).asJava) + + /** Extracts unnamed argument values from named argument list and returns it as unmodifiable `java.util.List`. + * + * E.g. for invocation obj.someDynamicMethod(a = 1, 2, b = 3, 4), returned list will be [2,4] + */ def unnamedArgsAsJavaList[AV](args: (String, AV)*) = - args.collect({ case ("", arg) => arg}).asJava - - /** - * Convenience trait that can be implemented by contexts passed as expression inputs to provide - * dynamic variable support. - * - * @tparam T - */ + args.collect { case ("", arg) => arg }.asJava + + /** Convenience trait that can be implemented by contexts passed as expression inputs to provide dynamic variable + * support. + * + * @tparam T + */ trait DynamicVariableSupport[T] extends Dynamic { def selectDynamic(name: String): T diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/DynamicVariableAccessor.scala b/scex-core/src/main/scala/com/avsystem/scex/util/DynamicVariableAccessor.scala index db92d66d..23c45913 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/DynamicVariableAccessor.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/DynamicVariableAccessor.scala @@ -5,9 +5,7 @@ import com.avsystem.scex.compiler.annotation.NotValidated import scala.language.dynamics -/** - * Created: 23-09-2013 - * Author: ghik +/** Created: 23-09-2013 Author: ghik */ class DynamicVariableAccessor[C <: ExpressionContext[_, V], V](ctx: C) extends TypedVariableAccessor(ctx) with Dynamic { @NotValidated def selectDynamic(name: String): V = diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/Fluent.scala b/scex-core/src/main/scala/com/avsystem/scex/util/Fluent.scala index 4c4f8b85..13bba245 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/Fluent.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/Fluent.scala @@ -1,9 +1,7 @@ package com.avsystem.scex package util -/** - * Created: 14-11-2013 - * Author: ghik +/** Created: 14-11-2013 Author: ghik */ trait Fluent { @inline diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/Literal.scala b/scex-core/src/main/scala/com/avsystem/scex/util/Literal.scala index 487fa797..da7e684f 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/Literal.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/Literal.scala @@ -3,10 +3,8 @@ package util import java.{lang => jl} -/** - * Created: 18-11-2013 - * Author: ghik - */ +/** Created: 18-11-2013 Author: ghik + */ final case class Literal(literalString: String) extends AnyVal { override def toString = literalString @@ -14,7 +12,8 @@ final case class Literal(literalString: String) extends AnyVal { def toChar: Char = if (literalString.length == 1) literalString.charAt(0) - else throw new IllegalArgumentException(s"Expected string with exactly one character, got ${'"'}$literalString${'"'}") + else + throw new IllegalArgumentException(s"Expected string with exactly one character, got ${'"'}$literalString${'"'}") def toByte: Byte = literalString.toByte diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/LoggingUtils.scala b/scex-core/src/main/scala/com/avsystem/scex/util/LoggingUtils.scala index b9b99ef0..d8b35a87 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/LoggingUtils.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/LoggingUtils.scala @@ -3,12 +3,10 @@ package util import org.slf4j.{Logger, LoggerFactory} -import scala.reflect.{ClassTag, classTag} +import scala.reflect.{classTag, ClassTag} -/** - * Created: 06-12-2013 - * Author: ghik - */ +/** Created: 06-12-2013 Author: ghik + */ trait LoggingUtils { protected case class LazyLogger(underlying: Logger) { diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/NamingThreadFactory.scala b/scex-core/src/main/scala/com/avsystem/scex/util/NamingThreadFactory.scala index 8b031757..8ba657e3 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/NamingThreadFactory.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/NamingThreadFactory.scala @@ -4,10 +4,8 @@ import java.util.concurrent.ThreadFactory import java.util.concurrent.atomic.AtomicInteger import scala.annotation.nowarn -/** - * Author: ghik - * Created: 25/01/16. - */ +/** Author: ghik Created: 25/01/16. + */ class NamingThreadFactory(prefix: String) extends ThreadFactory { private val group: ThreadGroup = { @nowarn("msg=deprecated") diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/PredefinedAccessSpecs.scala b/scex-core/src/main/scala/com/avsystem/scex/util/PredefinedAccessSpecs.scala index 3fd6c1e7..49c6d218 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/PredefinedAccessSpecs.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/PredefinedAccessSpecs.scala @@ -30,7 +30,7 @@ object PredefinedAccessSpecs { anyRef.notifyAll() anyRef.synchronized(_: Any) } - on { ip: RangedProxy[Any@plus] => + on { ip: RangedProxy[Any @plus] => ip.to(_: Any) ip.to(_: Any, _: Any) ip.until(_: Any) diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/SimpleContext.scala b/scex-core/src/main/scala/com/avsystem/scex/util/SimpleContext.scala index a774d094..06fd1f32 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/SimpleContext.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/SimpleContext.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.japi.JavaExpressionContext import scala.collection.mutable -/** - * Created: 23-09-2013 - * Author: ghik - */ +/** Created: 23-09-2013 Author: ghik + */ final case class SimpleContext[R](root: R) extends JavaExpressionContext[R, String] { private val variables = new mutable.HashMap[String, String] private val typedVariables = new mutable.HashMap[String, Any] diff --git a/scex-core/src/main/scala/com/avsystem/scex/util/TypesafeEquals.scala b/scex-core/src/main/scala/com/avsystem/scex/util/TypesafeEquals.scala index cf53c3a2..f41a0897 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/util/TypesafeEquals.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/util/TypesafeEquals.scala @@ -1,9 +1,7 @@ package com.avsystem.scex package util -/** - * Created: 20-11-2013 - * Author: ghik +/** Created: 20-11-2013 Author: ghik */ object TypesafeEquals { implicit def typesafeEqualsEnabled: TypesafeEqualsEnabled = null diff --git a/scex-core/src/main/scala/com/avsystem/scex/validation/SymbolValidator.scala b/scex-core/src/main/scala/com/avsystem/scex/validation/SymbolValidator.scala index 4c2e7cd2..176c0a55 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/validation/SymbolValidator.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/validation/SymbolValidator.scala @@ -1,7 +1,7 @@ package com.avsystem.scex package validation -import com.avsystem.scex.symboldsl.{SymbolDslMacros, SymbolDsl, SymbolInfo, SymbolInfoList} +import com.avsystem.scex.symboldsl.{SymbolDsl, SymbolDslMacros, SymbolInfo, SymbolInfoList} import com.avsystem.scex.util.CommonUtils._ import com.avsystem.scex.util.LoggingUtils @@ -14,11 +14,11 @@ trait SymbolValidator extends SymbolInfoList[Boolean] with LoggingUtils { def combine(otherValidator: SymbolValidator) = SymbolValidator(infoList ++ otherValidator.infoList) - lazy val referencedJavaClasses = infoList.iterator.flatMap({ + lazy val referencedJavaClasses = infoList.iterator.flatMap { case SymbolInfo(typeInfo, _, _, true) if typeInfo.isJava => typeInfo.clazz.toList.flatMap(hierarchy) case _ => Nil - }).toSet + }.toSet private lazy val specsLength = infoList.length @@ -29,19 +29,19 @@ trait SymbolValidator extends SymbolInfoList[Boolean] with LoggingUtils { import vc._ access match { - case access@SimpleMemberAccess(tpe, symbol, implicitConv, allowedByDefault, position) => + case access @ SimpleMemberAccess(tpe, symbol, implicitConv, allowedByDefault, position) => logger.trace(s"Validating access: $access") // SymbolInfos that match this invocation val matchingSpecs = matchingInfos(vc.universe)(tpe, symbol, implicitConv) - def specsRepr = matchingSpecs.map({ case InfoWithIndex(spec, idx) => s"$idx: $spec" }).mkString("\n") + def specsRepr = matchingSpecs.map { case InfoWithIndex(spec, idx) => s"$idx: $spec" }.mkString("\n") logger.trace(s"Matching signatures:\n$specsRepr") // get 'allow' field from matching spec that appeared first in ACL or false if there was no matching spec - val (allow, index) = matchingSpecs.headOption.map { - case InfoWithIndex(info, idx) => (info.payload, idx) - } getOrElse(allowedByDefault, lowestPriority(allowedByDefault)) + val (allow, index) = matchingSpecs.headOption.map { case InfoWithIndex(info, idx) => + (info.payload, idx) + } getOrElse (allowedByDefault, lowestPriority(allowedByDefault)) ValidationResult(index, if (allow) Nil else List(access)) @@ -79,19 +79,17 @@ object SymbolValidator extends SymbolDsl { val empty: SymbolValidator = apply(Nil) - /** - * Encloses block of statements that specify methods that are allowed to be called in expressions. - * Code inside allow block is virtualized - it's not actually compiled to bytecode. - * Multiple allow/deny blocks joined with ++ operator form an ACL-like structure. + /** Encloses block of statements that specify methods that are allowed to be called in expressions. Code inside + * allow block is virtualized - it's not actually compiled to bytecode. Multiple allow/deny blocks joined + * with ++ operator form an ACL-like structure. * @param expr * @return */ def allow(expr: Any): List[MemberAccessSpec] = macro SymbolDslMacros.allow_impl - /** - * Encloses block of statements that specify methods that are not allowed to be called in expressions. - * Code inside deny block is virtualized - it's not actually compiled to bytecode. - * Multiple allow/deny blocks joined with ++ operator form an ACL-like structure. + /** Encloses block of statements that specify methods that are not allowed to be called in expressions. Code inside + * deny block is virtualized - it's not actually compiled to bytecode. Multiple allow/deny blocks joined + * with ++ operator form an ACL-like structure. * @param expr * @return */ diff --git a/scex-core/src/main/scala/com/avsystem/scex/validation/SyntaxValidator.scala b/scex-core/src/main/scala/com/avsystem/scex/validation/SyntaxValidator.scala index 50a76864..143b0a6e 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/validation/SyntaxValidator.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/validation/SyntaxValidator.scala @@ -3,10 +3,8 @@ package validation import scala.reflect.macros.Universe - -/** - * Trait for expression syntax validator. This validator validates only language constructs, invocation validation - * is performed by SymbolValidator. +/** Trait for expression syntax validator. This validator validates only language constructs, invocation validation is + * performed by SymbolValidator. */ trait SyntaxValidator { def validateSyntax(u: Universe)(tree: u.Tree): (Boolean, List[u.Tree]) @@ -21,8 +19,8 @@ object SyntaxValidator { valDef.mods.hasFlag(Flag.PARAM) && valDef.rhs == EmptyTree tree match { - case _: Block | _: Select | _: Apply | _: TypeApply | _: Ident | - _: If | _: Literal | _: New | _: This | _: Typed | _: TypTree => + case _: Block | _: Select | _: Apply | _: TypeApply | _: Ident | _: If | _: Literal | _: New | _: This | + _: Typed | _: TypTree => (true, tree.children) case Function(valDefs, body) if valDefs.forall(isLambdaParamDef) => (true, body :: valDefs.map(_.tpt)) diff --git a/scex-core/src/main/scala/com/avsystem/scex/validation/ValidationContext.scala b/scex-core/src/main/scala/com/avsystem/scex/validation/ValidationContext.scala index 496bd045..ba6f5810 100644 --- a/scex-core/src/main/scala/com/avsystem/scex/validation/ValidationContext.scala +++ b/scex-core/src/main/scala/com/avsystem/scex/validation/ValidationContext.scala @@ -51,7 +51,7 @@ abstract class ValidationContext protected extends MacroUtils { symbol: Symbol, implicitConv: Option[Tree], allowedByDefault: Boolean, - pos: Position + pos: Position, ) extends MemberAccess { override def toString: String = @@ -86,30 +86,33 @@ abstract class ValidationContext protected extends MacroUtils { SimpleMemberAccess(rootTpe, symbol, None, allowedByDefault = false, tree.pos) - case Select(apply@ImplicitlyConverted(qualifier, fun), _) if !isScexSynthetic(fun.symbol) => - val accessByImplicit = SimpleMemberAccess(qualifier.tpe, tree.symbol, - Some(stripTypeApply(fun)), allowedByDefault = false, tree.pos) + case Select(apply @ ImplicitlyConverted(qualifier, fun), _) if !isScexSynthetic(fun.symbol) => + val accessByImplicit = + SimpleMemberAccess(qualifier.tpe, tree.symbol, Some(stripTypeApply(fun)), allowedByDefault = false, tree.pos) val implicitConversionAccess = extractAccess(fun, allowedSelectionPrefix = false) val plainAccess = SimpleMemberAccess(apply.tpe, tree.symbol, None, allowedByDefault = false, tree.pos) - val alternatives = AlternativeMemberAccess(List(accessByImplicit, MultipleMemberAccesses(List(implicitConversionAccess, plainAccess)))) + val alternatives = AlternativeMemberAccess( + List(accessByImplicit, MultipleMemberAccesses(List(implicitConversionAccess, plainAccess))) + ) // special case for configuration convenience: 'any + ' (using any2stringadd) is also validated as // combination of toString and string concatenation lazy val toStringMember = toStringSymbol(qualifier.tpe) val toStringAndConcatAccess = if (fun.symbol == any2stringadd && tree.symbol == stringAddPlus && toStringMember != NoSymbol) { - val toStringAccess = SimpleMemberAccess(qualifier.tpe, toStringMember, None, allowedByDefault = false, tree.pos) + val toStringAccess = + SimpleMemberAccess(qualifier.tpe, toStringMember, None, allowedByDefault = false, tree.pos) val stringConcatAccess = SimpleMemberAccess(stringTpe, stringConcat, None, allowedByDefault = false, tree.pos) MultipleMemberAccesses(List(toStringAccess, stringConcatAccess)) } else NoMemberAccess - MultipleMemberAccesses(List(alternatives, - toStringAndConcatAccess, - extractAccess(qualifier, allowedSelectionPrefix = false))) + MultipleMemberAccesses( + List(alternatives, toStringAndConcatAccess, extractAccess(qualifier, allowedSelectionPrefix = false)) + ) - case Select(apply@ImplicitlyConverted(qualifier, fun), _) - if tree.symbol.isMethod && isAdapterConversion(fun.symbol) && !isAdapterWrappedMember(tree.symbol) => + case Select(apply @ ImplicitlyConverted(qualifier, fun), _) + if tree.symbol.isMethod && isAdapterConversion(fun.symbol) && !isAdapterWrappedMember(tree.symbol) => val symbol = getJavaGetter(tree.symbol, qualifier.tpe) val access = SimpleMemberAccess(qualifier.tpe, symbol, None, allowedByDefault = false, tree.pos) @@ -122,8 +125,9 @@ abstract class ValidationContext protected extends MacroUtils { val staticMember = isStableStatic(qualifier.symbol) && !isFromToplevelType(tree.symbol) lazy val qualCompanion = qualifier.symbol.companion lazy val companionType = qualCompanion.asType.toType - val enumValueOf = staticMember && name == TermName("valueOf") && qualCompanion != NoSymbol && companionType <:< typeOf[Enum[_]] && - tree.symbol.isMethod && tree.symbol.asMethod.paramLists.flatten.map(_.typeSignature).corresponds(List(typeOf[String]))(_ =:= _) + val enumValueOf = staticMember && name == TermName("valueOf") && qualCompanion != NoSymbol && + companionType <:< typeOf[Enum[_]] && tree.symbol.isMethod && + tree.symbol.asMethod.paramLists.flatten.map(_.typeSignature).corresponds(List(typeOf[String]))(_ =:= _) val access = SimpleMemberAccess(qualifier.tpe, tree.symbol, None, allowedSelectionPrefix || enumValueOf, tree.pos) // When accessing member of static module (that includes Java statics), excluding getClass/equals/hashCode/toString/etc. @@ -133,9 +137,13 @@ abstract class ValidationContext protected extends MacroUtils { // special case for configuration convenience: string concatenation also forces validation of toString on its argument case Apply(qualifier, List(arg)) if qualifier.symbol == stringConcat => - MultipleMemberAccesses(List(toStringAccess(arg), - extractAccess(qualifier, allowedSelectionPrefix = false), - extractAccess(arg, allowedSelectionPrefix = false))) + MultipleMemberAccesses( + List( + toStringAccess(arg), + extractAccess(qualifier, allowedSelectionPrefix = false), + extractAccess(arg, allowedSelectionPrefix = false), + ) + ) case Apply(fun, List(arg)) if fun.symbol == safeToString => MultipleMemberAccesses(List(toStringAccess(arg), extractAccess(arg, allowedSelectionPrefix = false))) @@ -144,9 +152,10 @@ abstract class ValidationContext protected extends MacroUtils { // toString on its arguments case Apply(qualifier, args) if standardStringInterpolations contains qualifier.symbol => val toStringAccesses = MultipleMemberAccesses(args.map(toStringAccess)) - MultipleMemberAccesses(toStringAccesses :: - extractAccess(qualifier, allowedSelectionPrefix = false) :: - args.map(arg => extractAccess(arg, allowedSelectionPrefix = false))) + MultipleMemberAccesses( + toStringAccesses :: extractAccess(qualifier, allowedSelectionPrefix = false) :: + args.map(arg => extractAccess(arg, allowedSelectionPrefix = false)) + ) case _ => MultipleMemberAccesses(tree.children.map(child => extractAccess(child, allowedSelectionPrefix = false))) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ArbitraryCompilationTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ArbitraryCompilationTest.scala index a8f67dc7..afdbc8b5 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ArbitraryCompilationTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ArbitraryCompilationTest.scala @@ -5,10 +5,8 @@ import java.util.concurrent.Callable import java.{lang => jl, util => ju} import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 17-10-2013 - * Author: ghik - */ +/** Created: 17-10-2013 Author: ghik + */ class ArbitraryCompilationTest extends AnyFunSuite { val compiler = new DefaultScexCompiler(new ScexSettings) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassTaggedContext.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassTaggedContext.scala index 63ffb965..98c98ae7 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassTaggedContext.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassTaggedContext.scala @@ -5,9 +5,7 @@ import com.avsystem.scex.ExpressionContext import scala.collection.mutable import scala.reflect.ClassTag -/** - * Author: ghik - * Created: 22/10/15. +/** Author: ghik Created: 22/10/15. */ class ClassTaggedContext extends ExpressionContext[Unit, Unit] { type VarTag[T] = ClassTag[T] diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassfileReusingTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassfileReusingTest.scala index 076855d2..2da1e7be 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassfileReusingTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ClassfileReusingTest.scala @@ -13,10 +13,8 @@ import scala.reflect.internal.util.SourceFile import scala.reflect.io.AbstractFile import scala.tools.nsc.Global -/** - * Created: 22-10-2014 - * Author: ghik - */ +/** Created: 22-10-2014 Author: ghik + */ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { trait ScexCompilerInterceptor extends InterceptingPluginScexCompiler { @@ -37,17 +35,20 @@ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { } object compiler - extends ScexCompiler - with ScexCompilerInterceptor - with ScexPresentationCompiler - with ClassfileReusingScexCompiler { + extends ScexCompiler with ScexCompilerInterceptor with ScexPresentationCompiler with ClassfileReusingScexCompiler { val settings = new ScexSettings settings.classfileDirectory.value = "testClassfileCache" } - val testProfile = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, - SymbolValidator(PredefinedAccessSpecs.basicOperations), SymbolAttributes(Nil), "", NamedSource("", "")) + val testProfile = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + SymbolValidator(PredefinedAccessSpecs.basicOperations), + SymbolAttributes(Nil), + "", + NamedSource("", ""), + ) def applyIntExpr(expr: String) = compiler.getCompiledExpression[SimpleContext[Unit], Int](testProfile, expr, template = false).apply(SimpleContext(())) @@ -87,8 +88,14 @@ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { """ |implicit def implicitString1: String = "implicitString1" """.stripMargin - val profile1 = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, symbolValidator, - SymbolAttributes(Nil), "", NamedSource("test", utils1)) + val profile1 = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + symbolValidator, + SymbolAttributes(Nil), + "", + NamedSource("test", utils1), + ) val cexpr1 = compiler.getCompiledExpression[SimpleContext[Unit], String](profile1, expr, template = false) assert(cexpr1(SimpleContext(())) == "implicitString1") @@ -99,8 +106,14 @@ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { """ |implicit def implicitString2: String = "implicitString2" """.stripMargin - val profile2 = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, symbolValidator, - SymbolAttributes(Nil), "", NamedSource("test", utils2)) + val profile2 = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + symbolValidator, + SymbolAttributes(Nil), + "", + NamedSource("test", utils2), + ) val cexpr2 = compiler.getCompiledExpression[SimpleContext[Unit], String](profile2, expr, template = false) assert(cexpr2(SimpleContext(())) == "implicitString2") @@ -114,8 +127,14 @@ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { """ |def utilMethod(any: Any): Any = any """.stripMargin - val profile1 = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, symbolValidator, - SymbolAttributes(Nil), "", NamedSource("test", utils1)) + val profile1 = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + symbolValidator, + SymbolAttributes(Nil), + "", + NamedSource("test", utils1), + ) val cexpr1 = compiler.getCompiledExpression[SimpleContext[Unit], Any](profile1, expr, template = false) assert(cexpr1(SimpleContext(())) == 42) @@ -127,8 +146,14 @@ class ClassfileReusingTest extends AnyFunSuite with BeforeAndAfter { |def utilMethod(any: Any): Any = any |def utilMethod(int: Int): Any = int*2 """.stripMargin - val profile2 = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, symbolValidator, - SymbolAttributes(Nil), "", NamedSource("test", utils2)) + val profile2 = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + symbolValidator, + SymbolAttributes(Nil), + "", + NamedSource("test", utils2), + ) val cexpr2 = compiler.getCompiledExpression[SimpleContext[Unit], Any](profile2, expr, template = false) assert(cexpr2(SimpleContext(())) == 84) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/CompilationTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/CompilationTest.scala index bd487444..4799447e 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/CompilationTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/CompilationTest.scala @@ -28,7 +28,8 @@ trait CompilationTest extends BeforeAndAfterAll { this: Suite => } def catchAndPrint(code: => Any): Unit = - try code catch { + try code + catch { case NonFatal(ex) => ex.printStackTrace(System.out) } @@ -39,13 +40,25 @@ trait CompilationTest extends BeforeAndAfterAll { this: Suite => "test" + profileId } - def createProfile(acl: List[MemberAccessSpec] = Nil, attributes: List[SymbolInfo[Attributes]] = Nil, - header: String = "import com.avsystem.scex.compiler._", utils: String = "", dynamicVariablesEnabled: Boolean = true) = { + def createProfile( + acl: List[MemberAccessSpec] = Nil, + attributes: List[SymbolInfo[Attributes]] = Nil, + header: String = "import com.avsystem.scex.compiler._", + utils: String = "", + dynamicVariablesEnabled: Boolean = true, + ) = { val profileName = newProfileName() val expressionUtils = NamedSource(profileName, utils) - new ExpressionProfile(profileName, SyntaxValidator.SimpleExpressions, SymbolValidator(acl), - SymbolAttributes(attributes), header, expressionUtils, dynamicVariablesEnabled) + new ExpressionProfile( + profileName, + SyntaxValidator.SimpleExpressions, + SymbolValidator(acl), + SymbolAttributes(attributes), + header, + expressionUtils, + dynamicVariablesEnabled, + ) } def assertMemberAccessForbidden(expr: => Any): Unit = { @@ -54,12 +67,14 @@ trait CompilationTest extends BeforeAndAfterAll { this: Suite => } def evaluateTemplate[T: TypeString](expr: String, acl: List[MemberAccessSpec] = defaultAcl, header: String = "") = - compiler.getCompiledExpression[SimpleContext[Unit], T]( - createProfile(acl), expr, template = true, header = header).apply(SimpleContext(())) + compiler + .getCompiledExpression[SimpleContext[Unit], T](createProfile(acl), expr, template = true, header = header) + .apply(SimpleContext(())) - def evaluate[T: TypeString](expr: String, acl: List[MemberAccessSpec] = defaultAcl) = { - compiler.getCompiledExpression[SimpleContext[Unit], T](createProfile(acl), expr, template = false).apply(SimpleContext(())) - } + def evaluate[T: TypeString](expr: String, acl: List[MemberAccessSpec] = defaultAcl) = + compiler + .getCompiledExpression[SimpleContext[Unit], T](createProfile(acl), expr, template = false) + .apply(SimpleContext(())) def defaultAcl = PredefinedAccessSpecs.basicOperations } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/DynamicVariables.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/DynamicVariables.scala index 6ec20261..58900769 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/DynamicVariables.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/DynamicVariables.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.util.DynamicAdapters.DynamicVariableSupport import scala.collection.mutable -/** - * Created: 18-09-2013 - * Author: ghik - */ +/** Created: 18-09-2013 Author: ghik + */ class DynamicVariables extends DynamicVariableSupport[String] { private val map = new mutable.HashMap[String, String] diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/FancySplicedRoot.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/FancySplicedRoot.scala index 542ca98a..8bf8690a 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/FancySplicedRoot.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/FancySplicedRoot.scala @@ -3,10 +3,8 @@ package compiler import com.avsystem.scex.compiler.TemplateInterpolations.Splicer -/** - * Created: 31-03-2014 - * Author: ghik - */ +/** Created: 31-03-2014 Author: ghik + */ class FancySplicedRoot { def self = this } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/InterceptingPluginScexCompiler.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/InterceptingPluginScexCompiler.scala index 0d79b77a..5a23b363 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/InterceptingPluginScexCompiler.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/InterceptingPluginScexCompiler.scala @@ -3,10 +3,8 @@ package com.avsystem.scex.compiler import scala.tools.nsc._ import scala.tools.nsc.plugins.{Plugin, PluginComponent} -/** - * Created: 27-10-2014 - * Author: ghik - */ +/** Created: 27-10-2014 Author: ghik + */ trait InterceptingPluginScexCompiler extends ScexCompiler { protected def runsAfter: List[String] diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaScexCompilerTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaScexCompilerTest.scala index 2b5a0e45..62a7570c 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaScexCompilerTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaScexCompilerTest.scala @@ -1,7 +1,7 @@ package com.avsystem.scex.compiler import com.avsystem.scex.Expression -import com.avsystem.scex.compiler.CodeGeneration.{TypedVariables, escapedChar} +import com.avsystem.scex.compiler.CodeGeneration.{escapedChar, TypedVariables} import com.avsystem.scex.compiler.JavaScexCompilerTest.SuspiciousCharsAllowedInVariableNames import com.avsystem.scex.compiler.ScexCompiler.CompilationFailedException import com.avsystem.scex.japi.{ScalaTypeTokens, XmlFriendlyJavaScexCompiler} @@ -9,10 +9,8 @@ import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import com.avsystem.scex.validation.SymbolValidator.MemberAccessSpec import org.scalatest.funsuite.AnyFunSuite -/** - * Author: ghik - * Created: 26/10/15. - */ +/** Author: ghik Created: 26/10/15. + */ class JavaScexCompilerTest extends AnyFunSuite with CompilationTest { override protected def createCompiler = new XmlFriendlyJavaScexCompiler(new ScexSettings) @@ -74,7 +72,7 @@ class JavaScexCompilerTest extends AnyFunSuite with CompilationTest { private def compileExpression( expr: String, variableName: String, - accessControlList: List[MemberAccessSpec] = PredefinedAccessSpecs.basicOperations + accessControlList: List[MemberAccessSpec] = PredefinedAccessSpecs.basicOperations, ): Expression[SimpleContext[Unit], Double] = compiler.buildExpression .contextType(ScalaTypeTokens.create[SimpleContext[Unit]]) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaTypeParsingTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaTypeParsingTest.scala index 0f576bcf..f0d314d7 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaTypeParsingTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/JavaTypeParsingTest.scala @@ -48,7 +48,9 @@ class JavaTypeParsingTest extends AnyFunSuite { test("deeply nested parameterized classes") { assertResult("com.avsystem.scex.compiler.ParameterizedClass.StaticInnerGeneric[A]#DeeplyInnerGeneric[B] forSome {type A <: java.lang.Cloneable; type B}") { - javaTypeAsScalaType(classOf[ParameterizedClass.StaticInnerGeneric[A]#DeeplyInnerGeneric[B] forSome {type A; type B}]) + javaTypeAsScalaType( + classOf[ParameterizedClass.StaticInnerGeneric[A]#DeeplyInnerGeneric[B] forSome { type A; type B }] + ) } } @@ -75,4 +77,4 @@ class JavaTypeParsingTest extends AnyFunSuite { javaTypeAsScalaType(JavaTypes.partiallyWildcardedParameterizedType()) } } -} \ No newline at end of file +} diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/LiteralExpressionsTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/LiteralExpressionsTest.scala index 9e69f47d..ae832cf1 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/LiteralExpressionsTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/LiteralExpressionsTest.scala @@ -7,10 +7,8 @@ import com.avsystem.scex.compiler.TestUtils.CustomBooleanConversionRoot import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 04-04-2014 - * Author: ghik - */ +/** Created: 04-04-2014 Author: ghik + */ class LiteralExpressionsTest extends AnyFunSuite with CompilationTest { import com.avsystem.scex.validation.SymbolValidator._ @@ -95,7 +93,11 @@ class LiteralExpressionsTest extends AnyFunSuite with CompilationTest { } val cexpr = compiler.getCompiledExpression[SimpleContext[CustomBooleanConversionRoot], Boolean]( - createProfile(acl), "TRÓ", template = true, header = "") + createProfile(acl), + "TRÓ", + template = true, + header = "", + ) assert(cexpr(SimpleContext(new CustomBooleanConversionRoot("ZUO", "TRÓ")))) } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/OufOfDateUnitScexCompilerTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/OufOfDateUnitScexCompilerTest.scala index 7742c17f..db5cfba4 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/OufOfDateUnitScexCompilerTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/OufOfDateUnitScexCompilerTest.scala @@ -10,19 +10,16 @@ class OufOfDateUnitScexCompilerTest extends AnyFunSuite with CompilationTest { override protected def createCompiler: noCacheCompiler.type = noCacheCompiler object noCacheCompiler - extends ScexCompiler - with ScexPresentationCompiler - with JavaScexCompiler - with ClassfileReusingScexCompiler { + extends ScexCompiler with ScexPresentationCompiler with JavaScexCompiler with ClassfileReusingScexCompiler { val settings = new ScexSettings settings.classfileDirectory.value = "testClassfileCache" } - /** * - * Purpose of this test it to compile same expression using same profile multiple times with disabled caching to force execution of backgroundCompile method - * backgroundCompile was infinitely executed with changes introduced by 2.13.13 - */ + /** * Purpose of this test it to compile same expression using same profile multiple times with disabled caching to + * force execution of backgroundCompile method backgroundCompile was infinitely executed with changes introduced by + * 2.13.13 + */ test("out of date compilation") { val acl = PredefinedAccessSpecs.basicOperations val profile = createProfile(acl) @@ -41,5 +38,4 @@ class OufOfDateUnitScexCompilerTest extends AnyFunSuite with CompilationTest { compileExpression() } - } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ScalaParsingCommonsTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ScalaParsingCommonsTest.scala index 35e5cebe..ff78a464 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ScalaParsingCommonsTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ScalaParsingCommonsTest.scala @@ -3,10 +3,8 @@ package com.avsystem.scex.compiler import com.avsystem.scex.parsing.ScalaParsingCommons import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 31-10-2014 - * Author: ghik - */ +/** Created: 31-10-2014 Author: ghik + */ class ScalaParsingCommonsTest extends AnyFunSuite { import com.avsystem.scex.parsing.ScalaParsingCommons._ diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ScexCompilerTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ScexCompilerTest.scala index 53e10e66..0305c112 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ScexCompilerTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ScexCompilerTest.scala @@ -58,7 +58,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } val expr = "property + extraordinary + extraordinarilyBoxed + field + twice(42)" - val cexpr = compiler.getCompiledExpression[SimpleContext[JavaRoot], String](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[JavaRoot], String](createProfile(acl), expr, template = false) assert("propertytruefalse42.4284" == cexpr(SimpleContext(new JavaRoot))) } @@ -67,14 +68,19 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { on { m: ju.Map[_, _] => m.toString } - on { ct: (ParameterizedClass.StaticInnerGeneric[A]#DeeplyInnerGeneric[B] forSome {type A; type B}) => + on { ct: (ParameterizedClass.StaticInnerGeneric[A]#DeeplyInnerGeneric[B] forSome { type A; type B }) => ct.all.members } } type RootType = ParameterizedClass.StaticInnerGeneric[Cloneable]#DeeplyInnerGeneric[_] val expr = """ "EXPR:" + awesomeness + sampleMap + handleStuff("interesting stuff") + awesome + fjeld """ - val cexpr = compiler.buildExpression.contextType(new TypeToken[SimpleContext[RootType]] {}).template(false) - .resultType(classOf[String]).profile(createProfile(acl)).expression(expr).get + val cexpr = compiler.buildExpression + .contextType(new TypeToken[SimpleContext[RootType]] {}) + .template(false) + .resultType(classOf[String]) + .profile(createProfile(acl)) + .expression(expr) + .get val sig = new StaticInnerGeneric[Cloneable] assert("EXPR:true{}[interesting stuff handled]true[fjeld]" == cexpr(SimpleContext(new sig.DeeplyInnerGeneric[String]))) @@ -130,7 +136,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } val expr = "property" - val cexpr = compiler.getCompiledExpression[SimpleContext[JavaRoot], String](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[JavaRoot], String](createProfile(acl), expr, template = false) assert("property" == cexpr(SimpleContext(new JavaRoot))) } @@ -157,7 +164,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } val expr = "overriddenMethod()" - val cexpr = compiler.getCompiledExpression[SimpleContext[DerivedJavaRoot], Unit](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[DerivedJavaRoot], Unit](createProfile(acl), expr, template = false) cexpr(SimpleContext(new DerivedJavaRoot)) } @@ -167,14 +175,20 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } val expr = "new ArrayList[String]" val cexpr = compiler.getCompiledExpression[SimpleContext[Unit], ju.List[_]]( - createProfile(acl, header = "import java.util.ArrayList"), expr, template = false) + createProfile(acl, header = "import java.util.ArrayList"), + expr, + template = false, + ) assert(new ju.ArrayList[String] == cexpr(SimpleContext(()))) } test("utils test") { val expr = "utilValue" val cexpr = compiler.getCompiledExpression[SimpleContext[Unit], Int]( - createProfile(Nil, header = "", utils = "val utilValue = 42"), expr, template = false) + createProfile(Nil, header = "", utils = "val utilValue = 42"), + expr, + template = false, + ) assert(42 == cexpr(SimpleContext(()))) } @@ -185,7 +199,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { car.gimmeVar(_: String)(_: ExpressionContext[ContextAccessingRoot, String]) } } - val cexpr = compiler.getCompiledExpression[SimpleContext[ContextAccessingRoot], String](createProfile(acl), expr, template = false) + val cexpr = compiler + .getCompiledExpression[SimpleContext[ContextAccessingRoot], String](createProfile(acl), expr, template = false) val ctx = SimpleContext(new ContextAccessingRoot) ctx.setVariable("tehname", "tehvalue") assert("tehvalue" == cexpr(ctx)) @@ -237,7 +252,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { Some.apply(_: Any) } val expr = "Some(42)" - val cexpr = compiler.getCompiledExpression[SimpleContext[Unit], Option[Int]](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[Unit], Option[Int]](createProfile(acl), expr, template = false) assert(Some(42) == cexpr(SimpleContext(()))) } @@ -271,7 +287,10 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } val expr = "\"bippy\" ? \"fuu\"" val cexpr = compiler.getCompiledExpression[SimpleContext[Unit], String]( - createProfile(acl, header = "import com.avsystem.scex.compiler.TestExtensions._"), expr, template = false) + createProfile(acl, header = "import com.avsystem.scex.compiler.TestExtensions._"), + expr, + template = false, + ) assert("bippy" == cexpr(SimpleContext(()))) } @@ -326,19 +345,24 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } val header = "import com.avsystem.scex.compiler.ScexCompilerTest._" val expr = "_root(0)" - val cexpr = compiler.getCompiledExpression[SimpleContext[ju.List[String]], Any](createProfile(acl, header = header), expr, template = false) + val cexpr = compiler.getCompiledExpression[SimpleContext[ju.List[String]], Any]( + createProfile(acl, header = header), + expr, + template = false, + ) val list = ju.Arrays.asList("0", "1", "2") assert("0" == cexpr(SimpleContext(list))) } test("covariance by @plus annotation test") { val acl = allow { - on { l: ju.List[Any@plus] => + on { l: ju.List[Any @plus] => l.add(_: Any) } } val expr = "_root.add(\"string\")" - val cexpr = compiler.getCompiledExpression[SimpleContext[ju.List[String]], Unit](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[ju.List[String]], Unit](createProfile(acl), expr, template = false) val list = new ju.ArrayList[String] cexpr(SimpleContext(list)) assert("string" == list.get(0)) @@ -346,12 +370,13 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { test("contravariance by @minus annotation test") { val acl = allow { - on { l: ju.List[String@minus] => + on { l: ju.List[String @minus] => l.get _ } } val expr = "_root.get(0)" - val cexpr = compiler.getCompiledExpression[SimpleContext[ju.List[Any]], Any](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[ju.List[Any]], Any](createProfile(acl), expr, template = false) val list = ju.Arrays.asList[Any]("cos") cexpr(SimpleContext(list)) assert("cos" == list.get(0)) @@ -373,7 +398,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } val expr = "self.id" - val cexpr = compiler.getCompiledExpression[SimpleContext[SubRoot], String](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[SubRoot], String](createProfile(acl), expr, template = false) assert("tehId" == cexpr(SimpleContext(new SubRoot))) } @@ -401,7 +427,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } val expr = "that + _root.that" - val cexpr = compiler.getCompiledExpression[SimpleContext[Specialized], String](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[Specialized], String](createProfile(acl), expr, template = false) assert("thatthat" == cexpr(SimpleContext(new Specialized))) } @@ -433,7 +460,8 @@ class ScexCompilerTest extends AnyFunSuite with CompilationTest { } } - val cexpr = compiler.getCompiledExpression[SimpleContext[Unit], Boolean](createProfile(acl), expr, template = false) + val cexpr = + compiler.getCompiledExpression[SimpleContext[Unit], Boolean](createProfile(acl), expr, template = false) assert(cexpr(SimpleContext(()))) } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/SetterExpressionsTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/SetterExpressionsTest.scala index 12a7c7f6..866c4194 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/SetterExpressionsTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/SetterExpressionsTest.scala @@ -18,9 +18,8 @@ class SetterTarget { def lol = _lol - def lol_=(lol: Int) = { + def lol_=(lol: Int) = _lol = lol - } } @@ -36,9 +35,7 @@ object CustomBooleanSplicer { } } -/** - * Created: 28-11-2013 - * Author: ghik +/** Created: 28-11-2013 Author: ghik */ @nowarn("msg=a pure expression does nothing in statement position") class SetterExpressionsTest extends AnyFunSuite with CompilationTest { @@ -46,13 +43,16 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { import com.avsystem.scex.validation.SymbolValidator._ def applySetter[R: ClassTag: TypeString, T: TypeString]( - expr: String, root: R, value: T, + expr: String, + root: R, + value: T, acl: List[MemberAccessSpec] = PredefinedAccessSpecs.basicOperations, header: String = "", - template: Boolean = false) = { + template: Boolean = false, + ) = { - val setterExpression = compiler.getCompiledSetterExpression[SimpleContext[R], T]( - createProfile(acl), expr, template, header = header) + val setterExpression = + compiler.getCompiledSetterExpression[SimpleContext[R], T](createProfile(acl), expr, template, header = header) setterExpression.apply(SimpleContext(root)).apply(value) } @@ -89,7 +89,13 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { test("adapted root bean setter test with conversion") { val target = new JavaSetterTarget val header = "import SetterConversions._" - applySetter("awesome", target, "true", allow(on { st: JavaSetterTarget => st.all.introduced.members }), header = header) + applySetter( + "awesome", + target, + "true", + allow(on { st: JavaSetterTarget => st.all.introduced.members }), + header = header, + ) assert(target.isAwesome) } @@ -124,7 +130,13 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { test("adapted non-root template bean setter test") { val target = new JavaSetterTarget - applySetter("${self.beanprop}", target, 42, allow(on { st: JavaSetterTarget => st.all.introduced.members }), template = true) + applySetter( + "${self.beanprop}", + target, + 42, + allow(on { st: JavaSetterTarget => st.all.introduced.members }), + template = true, + ) assert(42 == target.self.getBeanprop) } @@ -143,8 +155,11 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { test("disabled dynamic variables setter test") { val expr = "_vars.lol" try { - compiler.getCompiledSetterExpression[SimpleContext[Unit], String](createProfile(Nil, dynamicVariablesEnabled = false), - expr, template = false) + compiler.getCompiledSetterExpression[SimpleContext[Unit], String]( + createProfile(Nil, dynamicVariablesEnabled = false), + expr, + template = false, + ) } catch { case CompilationFailedException(_, List(CompileError(source, column, msg))) => assert(source == expr) @@ -154,8 +169,8 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { } test("dynamic variable setter test") { - val setterExpression = compiler.getCompiledSetterExpression[SimpleContext[Unit], String]( - createProfile(Nil), "_vars.lol", template = false) + val setterExpression = compiler + .getCompiledSetterExpression[SimpleContext[Unit], String](createProfile(Nil), "_vars.lol", template = false) val context = SimpleContext(()) setterExpression.apply(context).apply("42") @@ -163,12 +178,13 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { } test("typed variable setter test") { - def setterExpression(dynamicVariablesEnabled: Boolean) = compiler.getCompiledSetterExpression[SimpleContext[Unit], Int]( - profile = createProfile(Nil, dynamicVariablesEnabled = dynamicVariablesEnabled), - expression = "_vars.lol", - template = false, - variableTypes = Map("lol" -> TypeString[Int]) - ) + def setterExpression(dynamicVariablesEnabled: Boolean) = + compiler.getCompiledSetterExpression[SimpleContext[Unit], Int]( + profile = createProfile(Nil, dynamicVariablesEnabled = dynamicVariablesEnabled), + expression = "_vars.lol", + template = false, + variableTypes = Map("lol" -> TypeString[Int]), + ) val context = SimpleContext(()) setterExpression(dynamicVariablesEnabled = true).apply(context).apply(42) @@ -180,7 +196,9 @@ class SetterExpressionsTest extends AnyFunSuite with CompilationTest { test("accepted type reporting test") { val acl = allow(on { st: JavaSetterTarget => st.all.introduced.members }) val setterExpression = compiler.getCompiledSetterExpression[SimpleContext[JavaSetterTarget], Nothing]( - createProfile(acl), "beanprop", template = false + createProfile(acl), + "beanprop", + template = false, ) val setter = setterExpression.apply(SimpleContext(new JavaSetterTarget)) assert(setter.acceptedType == Type("Int", classOf[Int])) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ShiftInfoPositionMappingTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ShiftInfoPositionMappingTest.scala index bc4a9682..416dc7fa 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ShiftInfoPositionMappingTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ShiftInfoPositionMappingTest.scala @@ -6,9 +6,7 @@ import org.scalatest.funsuite.AnyFunSuite import scala.collection.immutable.SortedMap -/** - * Created: 24-10-2013 - * Author: ghik +/** Created: 24-10-2013 Author: ghik */ class ShiftInfoPositionMappingTest extends AnyFunSuite { test("empty mapping test") { @@ -25,9 +23,12 @@ class ShiftInfoPositionMappingTest extends AnyFunSuite { test("something was added at the beginning") { val added = 5 - val mapping = new ShiftInfoPositionMapping(SortedMap( - 0 -> ShiftInfo(0, added, Binding.Left) - ), null) + val mapping = new ShiftInfoPositionMapping( + SortedMap( + 0 -> ShiftInfo(0, added, Binding.Left) + ), + null, + ) for (i <- -5 until 0) { assert(mapping(i) == i) @@ -39,9 +40,12 @@ class ShiftInfoPositionMappingTest extends AnyFunSuite { test("something was removed at the beginning") { val removed = 5 - val mapping = new ShiftInfoPositionMapping(SortedMap( - 0 -> ShiftInfo(0, -removed, Binding.Right) - ), null) + val mapping = new ShiftInfoPositionMapping( + SortedMap( + 0 -> ShiftInfo(0, -removed, Binding.Right) + ), + null, + ) for (i <- -5 until 0) { assert(mapping(i) == i) @@ -57,9 +61,12 @@ class ShiftInfoPositionMappingTest extends AnyFunSuite { test("something was added and removed at the beginning") { val added = 3 val removed = 5 - val mapping = new ShiftInfoPositionMapping(SortedMap( - 0 -> ShiftInfo(0, added, removed, Binding.Right) - ), null) + val mapping = new ShiftInfoPositionMapping( + SortedMap( + 0 -> ShiftInfo(0, added, removed, Binding.Right) + ), + null, + ) for (i <- -5 until 0) { assert(mapping(i) == i) @@ -77,13 +84,16 @@ class ShiftInfoPositionMappingTest extends AnyFunSuite { 0123 45678 901234567 oooraaaaaoorrraorroooooo 012334567890000122234567 - */ + */ - val mapping = new ShiftInfoPositionMapping(SortedMap( - 3 -> ShiftInfo(0, 5, 1, Binding.Left), - 6 -> ShiftInfo(4, 1, 3, Binding.Left), - 10 -> ShiftInfo(2, 0, 2, Binding.Right) - ), null) + val mapping = new ShiftInfoPositionMapping( + SortedMap( + 3 -> ShiftInfo(0, 5, 1, Binding.Left), + 6 -> ShiftInfo(4, 1, 3, Binding.Left), + 10 -> ShiftInfo(2, 0, 2, Binding.Right), + ), + null, + ) val results = Array(0, 1, 2, 3, 8, 9, 10, 10, 10, 11, 12, 12, 12, 13, 14, 15, 16, 17, 18) for (i <- -5 until 0) { diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/SomeDynamic.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/SomeDynamic.scala index 185d1375..dc9c1544 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/SomeDynamic.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/SomeDynamic.scala @@ -3,10 +3,8 @@ package compiler import scala.language.dynamics -/** - * Created: 8/8/13 - * Author: ghik - */ +/** Created: 8/8/13 Author: ghik + */ object SomeDynamic extends Dynamic { def selectDynamic(attr: String) = attr } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateExpressionsTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateExpressionsTest.scala index 291509dc..8a2e03ec 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateExpressionsTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateExpressionsTest.scala @@ -9,10 +9,8 @@ import org.scalatest.funsuite.AnyFunSuite import scala.annotation.nowarn -/** - * Created: 18-11-2013 - * Author: ghik - */ +/** Created: 18-11-2013 Author: ghik + */ @nowarn("msg=a pure expression does nothing in statement position") class TemplateExpressionsTest extends AnyFunSuite with CompilationTest { @@ -61,7 +59,10 @@ class TemplateExpressionsTest extends AnyFunSuite with CompilationTest { FancySplicedRoot.fancySplicer.toString(_: FancySplicedRoot) } val cexpr = compiler.getCompiledExpression[SimpleContext[FancySplicedRoot], String]( - createProfile(acl), "${self}stuff", template = true) + createProfile(acl), + "${self}stuff", + template = true, + ) assert("FANCYstuff" == cexpr.apply(SimpleContext(new FancySplicedRoot))) } @@ -78,11 +79,15 @@ class TemplateExpressionsTest extends AnyFunSuite with CompilationTest { } test("enum from string test") { - assert(RetentionPolicy.RUNTIME == evaluateTemplate[RetentionPolicy]("${\"RUNTIME\"}", allow(RetentionPolicy.valueOf _))) + assert( + RetentionPolicy.RUNTIME == evaluateTemplate[RetentionPolicy]("${\"RUNTIME\"}", allow(RetentionPolicy.valueOf _)) + ) } test("enum literally test") { - assert(RetentionPolicy.RUNTIME == evaluateTemplate[RetentionPolicy]("${java.lang.annotation.RetentionPolicy.RUNTIME}")) + assert( + RetentionPolicy.RUNTIME == evaluateTemplate[RetentionPolicy]("${java.lang.annotation.RetentionPolicy.RUNTIME}") + ) } test("interpolation argument inference test") { @@ -92,7 +97,10 @@ class TemplateExpressionsTest extends AnyFunSuite with CompilationTest { } } val cexpr = compiler.getCompiledExpression[SimpleContext[ValueRoot[String]], String]( - createProfile(acl), "${if(value.endsWith(\"lol\")) value + \"lol\" else value}", template = true) + createProfile(acl), + "${if(value.endsWith(\"lol\")) value + \"lol\" else value}", + template = true, + ) assert("fuulollol" == cexpr(SimpleContext(new ValueRoot("fuulol")))) } @@ -104,7 +112,10 @@ class TemplateExpressionsTest extends AnyFunSuite with CompilationTest { } } val cexpr = compiler.getCompiledExpression[SimpleContext[ValueRoot[String]], String]( - createProfile(acl), "${if(value.endsWith(\"lol\")) value + \"lol\" else value}${123}", template = true) + createProfile(acl), + "${if(value.endsWith(\"lol\")) value + \"lol\" else value}${123}", + template = true, + ) assert("fuulollol123" == cexpr(SimpleContext(new ValueRoot("fuulol")))) } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateParserTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateParserTest.scala index c258ea81..4ba45c9d 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateParserTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/TemplateParserTest.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.parsing.TemplateParser import com.google.common.io.ByteStreams import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 03-11-2014 - * Author: ghik - */ +/** Created: 03-11-2014 Author: ghik + */ class TemplateParserTest extends AnyFunSuite { def parse(expr: String): (List[String], List[String]) = { val (parts, args) = TemplateParser.parseTemplate(expr).get diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/TestExtensions.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/TestExtensions.scala index 6298c9f1..ba3fc0d6 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/TestExtensions.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/TestExtensions.scala @@ -2,10 +2,8 @@ package com.avsystem.scex.compiler import scala.annotation.nowarn -/** - * Author: ghik - * Created: 19/10/15. - */ +/** Author: ghik Created: 19/10/15. + */ object TestExtensions { @nowarn("msg=Implicit classes") implicit class any2qmark[A](a: => A) { diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/TestUtils.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/TestUtils.scala index 2fcd78af..4e05e1df 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/TestUtils.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/TestUtils.scala @@ -3,10 +3,8 @@ package compiler import com.avsystem.scex.util.Literal -/** - * Created: 04-04-2014 - * Author: ghik - */ +/** Created: 04-04-2014 Author: ghik + */ object TestUtils { implicit def zeroOneLiteralToBoolean(lit: Literal): Boolean = lit.literalString match { case "0" => false diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/TypesafeEqualsTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/TypesafeEqualsTest.scala index 330b587a..96ba0996 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/TypesafeEqualsTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/TypesafeEqualsTest.scala @@ -8,17 +8,24 @@ import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import com.avsystem.scex.validation.{SymbolValidator, SyntaxValidator} import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 20-11-2013 - * Author: ghik +/** Created: 20-11-2013 Author: ghik */ class TypesafeEqualsTest extends AnyFunSuite with CompilationTest { import com.avsystem.scex.validation.SymbolValidator._ - override def evaluate[T: TypeString](expr: String, acl: List[MemberAccessSpec] = PredefinedAccessSpecs.basicOperations) = { - val profile = new ExpressionProfile(newProfileName(), SyntaxValidator.SimpleExpressions, SymbolValidator(acl), - SymbolAttributes(Nil), "import com.avsystem.scex.util.TypesafeEquals._", NamedSource("test", "")) + override def evaluate[T: TypeString]( + expr: String, + acl: List[MemberAccessSpec] = PredefinedAccessSpecs.basicOperations, + ) = { + val profile = new ExpressionProfile( + newProfileName(), + SyntaxValidator.SimpleExpressions, + SymbolValidator(acl), + SymbolAttributes(Nil), + "import com.avsystem.scex.util.TypesafeEquals._", + NamedSource("test", ""), + ) compiler.getCompiledExpression[SimpleContext[Unit], T](profile, expr, template = false).apply(SimpleContext(())) } @@ -60,7 +67,7 @@ class TypesafeEqualsTest extends AnyFunSuite with CompilationTest { } test("complex expression test") { - assert(true == evaluate[Boolean]( """("fuu" == "lol") || ("dafuq" != "srsly") """)) + assert(true == evaluate[Boolean]("""("fuu" == "lol") || ("dafuq" != "srsly") """)) } } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/ValueRoot.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/ValueRoot.scala index 322c05b9..b9270857 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/ValueRoot.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/ValueRoot.scala @@ -1,8 +1,6 @@ package com.avsystem.scex package compiler -/** - * Created: 20-10-2014 - * Author: ghik - */ +/** Created: 20-10-2014 Author: ghik + */ class ValueRoot[V](val value: V) diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/CompletionTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/CompletionTest.scala index 40c7adf0..c569d277 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/CompletionTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/CompletionTest.scala @@ -4,14 +4,12 @@ import com.avsystem.commons.misc.TypeString import com.avsystem.scex.Type import com.avsystem.scex.compiler.presentation.ScexPresentationCompiler.{Member, Param} -import scala.reflect.{ClassTag, classTag} +import scala.reflect.{classTag, ClassTag} -/** - * Author: ghik - * Created: 11/18/14. +/** Author: ghik Created: 11/18/14. */ trait CompletionTest { - protected def scexType[T: TypeString : ClassTag]: Type = + protected def scexType[T: TypeString: ClassTag]: Type = Type(TypeString.of[T], classTag[T].runtimeClass) case class PartialMember( @@ -19,13 +17,10 @@ trait CompletionTest { returnType: Type, params: List[List[Param]] = Nil, implicitParams: List[Param] = Nil, - doc: String = null) + doc: String = null, + ) - def asPartial(member: Member) = PartialMember( - member.name, - member.returnType, - member.params, - member.implicitParams, - member.documentation.orNull) + def asPartial(member: Member) = + PartialMember(member.name, member.returnType, member.params, member.implicitParams, member.documentation.orNull) } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/ScopeAndTypeCompletionTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/ScopeAndTypeCompletionTest.scala index c82d0643..8d504aa0 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/ScopeAndTypeCompletionTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/ScopeAndTypeCompletionTest.scala @@ -10,9 +10,7 @@ import org.scalatest.funsuite.AnyFunSuite import scala.annotation.nowarn -/** - * Author: ghik - * Created: 11/18/14. +/** Author: ghik Created: 11/18/14. */ @nowarn("msg=a pure expression does nothing in statement position") class ScopeAndTypeCompletionTest extends AnyFunSuite with CompilationTest with CompletionTest { @@ -75,61 +73,85 @@ class ScopeAndTypeCompletionTest extends AnyFunSuite with CompilationTest with C val completer = compiler.getCompleter[SimpleContext[Unit], Any](profile, template = false) val completion = completer.getTypeCompletion("\"\".", 2).passTo(c => c.copy(members = c.members.sortBy(_.name))) - assert(completion.members.map(asPartial) == Vector( - PartialMember("charAt", scexType[Char], List(List(Param("index", scexType[Int]))), doc = "doc of charAt"), - PartialMember("empty", scexType[Boolean]), - PartialMember("isEmpty", scexType[Boolean], List(Nil)), - PartialMember("toInt", scexType[Int]) - )) + assert( + completion.members.map(asPartial) == Vector( + PartialMember("charAt", scexType[Char], List(List(Param("index", scexType[Int]))), doc = "doc of charAt"), + PartialMember("empty", scexType[Boolean]), + PartialMember("isEmpty", scexType[Boolean], List(Nil)), + PartialMember("toInt", scexType[Int]), + ) + ) } test("attribute annotations test") { val completer = compiler.getCompleter[SimpleContext[Root], Any](profile, template = false) val completion = completer.getTypeCompletion("_root.", 5).passTo(c => c.copy(members = c.members.sortBy(_.name))) - assert(completion.members.map(asPartial) === Vector( - PartialMember("com", scexType[Int]), - PartialMember("implicitMethod", scexType[Int], doc = "implicit method doc"), - PartialMember("method", scexType[Any], List(List( - Param("annotArg", scexType[Any]), - Param("moar", scexType[Any]) - )), doc = "handles stuff") - )) + assert( + completion.members.map(asPartial) === Vector( + PartialMember("com", scexType[Int]), + PartialMember("implicitMethod", scexType[Int], doc = "implicit method doc"), + PartialMember( + "method", + scexType[Any], + List( + List( + Param("annotArg", scexType[Any]), + Param("moar", scexType[Any]), + ) + ), + doc = "handles stuff", + ), + ) + ) } test("simple scope completion test") { val completer = compiler.getCompleter[SimpleContext[Root], Any](profile, template = false) val completion = completer.getScopeCompletion.passTo(c => c.copy(members = c.members.sortBy(_.name))) - assert(completion.members.filterNot(_.flags.iimplicit).map(asPartial) == Vector( - PartialMember("com", scexType[Int]), // test shadowing of toplevel package - PartialMember("method", scexType[Any], List(List( - Param("annotArg", scexType[Any]), - Param("moar", scexType[Any]) - )), doc = "handles stuff"), - PartialMember("utilStuff", scexType[Int], doc = "util stuff") - )) + assert( + completion.members.filterNot(_.flags.iimplicit).map(asPartial) == Vector( + PartialMember("com", scexType[Int]), // test shadowing of toplevel package + PartialMember( + "method", + scexType[Any], + List( + List( + Param("annotArg", scexType[Any]), + Param("moar", scexType[Any]), + ) + ), + doc = "handles stuff", + ), + PartialMember("utilStuff", scexType[Int], doc = "util stuff"), + ) + ) } test("scope completion test with adapted getters") { val completer = compiler.getCompleter[SimpleContext[JavaRootWithGetter], Any](profile, template = false) val completion = completer.getScopeCompletion.passTo(c => c.copy(members = c.members.sortBy(_.name))) - assert(completion.members.filterNot(_.flags.iimplicit).map(asPartial) == Vector( - PartialMember("getName", scexType[String], List(Nil)), - PartialMember("name", scexType[String]), - PartialMember("utilStuff", scexType[Int], doc = "util stuff") - )) + assert( + completion.members.filterNot(_.flags.iimplicit).map(asPartial) == Vector( + PartialMember("getName", scexType[String], List(Nil)), + PartialMember("name", scexType[String]), + PartialMember("utilStuff", scexType[Int], doc = "util stuff"), + ) + ) } test("type completion test with adapted getters") { val completer = compiler.getCompleter[SimpleContext[JavaRootWithGetter], Any](profile, template = false) val completion = completer.getTypeCompletion("_root.", 5).passTo(c => c.copy(members = c.members.sortBy(_.name))) - assert(completion.members.map(asPartial) == Vector( - PartialMember("getName", scexType[String], List(Nil)), - PartialMember("name", scexType[String]) - )) + assert( + completion.members.map(asPartial) == Vector( + PartialMember("getName", scexType[String], List(Nil)), + PartialMember("name", scexType[String]), + ) + ) } test("literal as Any") { diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/TypeCompletionPrefixTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/TypeCompletionPrefixTest.scala index c8029e21..4a0c507d 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/TypeCompletionPrefixTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/presentation/TypeCompletionPrefixTest.scala @@ -11,10 +11,8 @@ import org.scalatest.funsuite.AnyFunSuite import scala.annotation.nowarn -/** - * Created: 07-10-2014 - * Author: ghik - */ +/** Created: 07-10-2014 Author: ghik + */ @nowarn("msg=a pure expression does nothing in statement position") class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with CompletionTest { @@ -47,11 +45,15 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com } private def createCompleter(acl: List[MemberAccessSpec], template: Boolean) = - compiler.getCompleter[SimpleContext[Root], Any](createProfile(acl), template, header = header, - variableTypes = Map("someInt" -> TypeString[Int])) + compiler.getCompleter[SimpleContext[Root], Any]( + createProfile(acl), + template, + header = header, + variableTypes = Map("someInt" -> TypeString[Int]), + ) private def assertPrefix(exprWithCaret: String, expectedPrefix: String, expectedType: Type, template: Boolean): Unit = { - val exprWithSplice = if(!template) exprWithCaret else s"$${$exprWithCaret}" + val exprWithSplice = if (!template) exprWithCaret else s"$${$exprWithCaret}" val completer = createCompleter(acl, template) val offset = exprWithSplice.indexOf('|') - 1 val expr = exprWithSplice.substring(0, offset + 1) + exprWithSplice.substring(offset + 2) @@ -75,7 +77,14 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com assert(completion.members.isEmpty) } - private def tests(namePrefix: String, expectedPrefix: String, expectedType: Type)(exprs: String*)(implicit pos: Position): Unit = { + private def tests( + namePrefix: String, + expectedPrefix: String, + expectedType: Type, + )( + exprs: String* + )(implicit pos: Position + ): Unit = { exprs.foreach { exprWithCaret => test(namePrefix + " " + exprWithCaret) { assertPrefix(exprWithCaret, expectedPrefix, expectedType, template = false) @@ -94,31 +103,31 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com tests("literal")( "123|", - "1|23" + "1|23", ) tests("plain identifier")( "api|", - "ap|i" + "ap|i", ) tests("variable reference")( "#|", "#lo|", "#lo|l", - "#|lol" + "#|lol", ) tests("space after selection")( "api. |", - "api.co |" + "api.co |", ) tests("inside argument list")( "api.aaa.substring(|", "api.aaa.substring(32|", "api.aaa.substring(32,|", - "api.aaa.substring(32, |" + "api.aaa.substring(32, |", ) tests("plain selection", "api", scexType[Api])( @@ -128,32 +137,32 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com "api.|aaa", "api.aaa|.inc", "api.aa|a.inc", - "api.|aaa.inc" + "api.|aaa.inc", ) tests("plain selection with dangling dot", "api.aaa", scexType[String])( "api.aaa.inc|", "api.aaa.in|c", - "api.aaa.|inc" + "api.aaa.|inc", ) tests("incomplete selection", "api", scexType[Api])( "api.inc|", "api.i|nc", - "api.|inc" + "api.|inc", ) tests("incomplete selection accidentally keyword", "api", scexType[Api])( "api.type|", "api.typ|e", "api.t|ype", - "api.|type" + "api.|type", ) tests("forbidden selection", "api", scexType[Api])( "api.zuo|", "api.z|uo", - "api.|zuo" + "api.|zuo", ) tests("plain select dynamic", "dyn", scexType[Dyn])( @@ -166,35 +175,35 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com "dyn.|whatevs.", "dyn.whatevs|.inc", "dyn.whatev|s.inc", - "dyn.|whatevs.inc" + "dyn.|whatevs.inc", ) tests("select dynamic incomplete selection", "dyn.whatevs", scexType[Api])( "dyn.whatevs.|", "dyn.whatevs.inc|", "dyn.whatevs.i|nc", - "dyn.whatevs.|inc" + "dyn.whatevs.|inc", ) tests("select dynamic incomplete subselection", "api.dynStr.lol", scexType[String])( "api.dynStr.lol.|", "api.dynStr.lol.is|", "api.dynStr.lol.i|s", - "api.dynStr.lol.|is" + "api.dynStr.lol.|is", ) tests("argument-positioned select dynamic incomplete subselection", "api.dynStr.lol", scexType[String])( "api.dynStr.fuu + api.dynStr.lol.|", "api.dynStr.fuu + api.dynStr.lol.is|", "api.dynStr.fuu + api.dynStr.lol.i|s", - "api.dynStr.fuu + api.dynStr.lol.|is" + "api.dynStr.fuu + api.dynStr.lol.|is", ) tests("select dynamic complete subselection", "api.dynStr.lol", scexType[String])( "api.dynStr.lol.isEmpty|", "api.dynStr.lol.isEmpt|y", "api.dynStr.lol.isEmpty|.", - "api.dynStr.lol.isEm|pty." + "api.dynStr.lol.isEm|pty.", ) tests("select dynamic sub-subselection", "dyn.abc.aaa", scexType[String])( @@ -202,67 +211,67 @@ class TypeCompletionPrefixTest extends AnyFunSuite with CompilationTest with Com "dyn.abc.aaa.i|", "dyn.abc.aaa.i|s", "dyn.abc.aaa.|is", - "dyn.abc.aaa.is|" + "dyn.abc.aaa.is|", ) tests("double select dynamic", "api.dyn.fuu.dynStr", scexType[DynStr])( "api.dyn.fuu.dynStr.|", "api.dyn.fuu.dynStr.i|s", "api.dyn.fuu.dynStr.is|", - "api.dyn.fuu.dynStr.|is" + "api.dyn.fuu.dynStr.|is", ) tests("double select dynamic subselection", "api.dyn.fuu.dynStr.krap", scexType[String])( "api.dyn.fuu.dynStr.krap.|", "api.dyn.fuu.dynStr.krap.i|s", "api.dyn.fuu.dynStr.krap.is|", - "api.dyn.fuu.dynStr.krap.|is" + "api.dyn.fuu.dynStr.krap.|is", ) tests("argument-positioned select dynamic complete subselection", "api.dynStr.lol", scexType[String])( "api.dynStr.fuu + api.dynStr.lol.isEmpty|", "api.dynStr.fuu + api.dynStr.lol.isEmpt|y", "api.dynStr.fuu + api.dynStr.lol.isEmpty|.", - "api.dynStr.fuu + api.dynStr.lol.isEm|pty." + "api.dynStr.fuu + api.dynStr.lol.isEm|pty.", ) tests("argument-positioned double select dynamic", "api.dyn.fuu.dynStr", scexType[DynStr])( "api.dynStr.fuu + api.dyn.fuu.dynStr.|", "api.dynStr.fuu + api.dyn.fuu.dynStr.i|s", "api.dynStr.fuu + api.dyn.fuu.dynStr.is|", - "api.dynStr.fuu + api.dyn.fuu.dynStr.|is" + "api.dynStr.fuu + api.dyn.fuu.dynStr.|is", ) tests("argument-positioned double select dynamic subselection", "api.dyn.fuu.dynStr.krap", scexType[String])( "api.dynStr.fuu + api.dyn.fuu.dynStr.krap.|", "api.dynStr.fuu + api.dyn.fuu.dynStr.krap.i|s", "api.dynStr.fuu + api.dyn.fuu.dynStr.krap.is|", - "api.dynStr.fuu + api.dyn.fuu.dynStr.krap.|is" + "api.dynStr.fuu + api.dyn.fuu.dynStr.krap.|is", ) tests("select dynamic forbidden selection", "dyn.whatevs", scexType[Api])( "dyn.whatevs.zuo|", "dyn.whatevs.z|uo", - "dyn.whatevs.|zuo" + "dyn.whatevs.|zuo", ) tests("empty param list method selection", "api", scexType[Api])( "api.ccc|.", "api.ccc|", "api.cc|c", - "api.|ccc" + "api.|ccc", ) tests("forbidden implicit member selection", "api", scexType[Api])( "api.zle|", "api.zl|e", - "api.|zle" + "api.|zle", ) tests("typed dynamic variable member selection", "_vars.someInt", scexType[Int])( "_vars.someInt.|", "_vars.someInt.|lol", - "_vars.someInt.l|ol" + "_vars.someInt.l|ol", ) } @@ -309,4 +318,4 @@ object TypeCompletionPrefixTest { implicit def apiToExt(api: Api): ExtApi = ??? -} \ No newline at end of file +} diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/PStringTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/PStringTest.scala index fb092e65..6a366ad3 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/PStringTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/PStringTest.scala @@ -6,13 +6,18 @@ import org.scalatest.funsuite.AnyFunSuite import scala.collection.immutable.SortedMap -/** - * Created: 25-10-2013 - * Author: ghik +/** Created: 25-10-2013 Author: ghik */ class PStringTest extends AnyFunSuite { - def test(name: String)(modifications: Modification*) - (shiftMapping: (Int, ShiftInfo)*)(reverseShiftMapping: (Int, ShiftInfo)*): Unit = super.test(name) { + def test( + name: String + )( + modifications: Modification* + )( + shiftMapping: (Int, ShiftInfo)* + )( + reverseShiftMapping: (Int, ShiftInfo)* + ): Unit = super.test(name) { val (actualShiftMapping, actualReverseShiftMapping) = PString.computeMapping(modifications.toList, Nil, Nil) @@ -22,44 +27,40 @@ class PStringTest extends AnyFunSuite { test("no modifications test")()()() - test("single add test")( - Modification(0, 5, Binding.Left))( - 0 -> ShiftInfo(0, 5, 0, Binding.Left))( - 0 -> ShiftInfo(0, 0, 5, Binding.Left)) + test("single add test")(Modification(0, 5, Binding.Left))(0 -> ShiftInfo(0, 5, 0, Binding.Left))( + 0 -> ShiftInfo(0, 0, 5, Binding.Left) + ) - test("single remove test")( - Modification(0, -5, Binding.Left))( - 0 -> ShiftInfo(0, 0, 5, Binding.Left))( - 0 -> ShiftInfo(0, 5, 0, Binding.Left)) + test("single remove test")(Modification(0, -5, Binding.Left))(0 -> ShiftInfo(0, 0, 5, Binding.Left))( + 0 -> ShiftInfo(0, 5, 0, Binding.Left) + ) - test("remove+add replace test")( - Modification(0, -5, Binding.Left), Modification(0, 3, Binding.Left))( - 0 -> ShiftInfo(0, 3, 5, Binding.Left))( - 0 -> ShiftInfo(0, 5, 3, Binding.Left)) + test("remove+add replace test")(Modification(0, -5, Binding.Left), Modification(0, 3, Binding.Left))( + 0 -> ShiftInfo(0, 3, 5, Binding.Left) + )(0 -> ShiftInfo(0, 5, 3, Binding.Left)) - test("add+remove replace test")( - Modification(0, 3, Binding.Left), Modification(0, -5, Binding.Left))( - 0 -> ShiftInfo(0, 3, 5, Binding.Left))( - 0 -> ShiftInfo(0, 5, 3, Binding.Left)) + test("add+remove replace test")(Modification(0, 3, Binding.Left), Modification(0, -5, Binding.Left))( + 0 -> ShiftInfo(0, 3, 5, Binding.Left) + )(0 -> ShiftInfo(0, 5, 3, Binding.Left)) - test("consecutive remove and add test")( - Modification(0, -5, Binding.Left), Modification(5, 3, Binding.Left))( - 0 -> ShiftInfo(0, 0, 5, Binding.Left), 5 -> ShiftInfo(-5, 3, 0, Binding.Left))( - 0 -> ShiftInfo(0, 5, 3, Binding.Left)) + test("consecutive remove and add test")(Modification(0, -5, Binding.Left), Modification(5, 3, Binding.Left))( + 0 -> ShiftInfo(0, 0, 5, Binding.Left), + 5 -> ShiftInfo(-5, 3, 0, Binding.Left), + )(0 -> ShiftInfo(0, 5, 3, Binding.Left)) test("complex test")( Modification(2, 5, Binding.Left), Modification(3, -4, Binding.Left), Modification(10, -2, Binding.Left), - Modification(12, 4, Binding.Left) + Modification(12, 4, Binding.Left), )( 2 -> ShiftInfo(0, 5, 0, Binding.Left), 3 -> ShiftInfo(5, 0, 4, Binding.Left), 10 -> ShiftInfo(1, 0, 2, Binding.Left), - 12 -> ShiftInfo(-1, 4, 0, Binding.Left) + 12 -> ShiftInfo(-1, 4, 0, Binding.Left), )( 2 -> ShiftInfo(0, 0, 5, Binding.Left), 8 -> ShiftInfo(-5, 4, 0, Binding.Left), - 11 -> ShiftInfo(-1, 2, 4, Binding.Left) + 11 -> ShiftInfo(-1, 2, 4, Binding.Left), ) } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyCompilerTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyCompilerTest.scala index 6da065f8..21dc1562 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyCompilerTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyCompilerTest.scala @@ -9,12 +9,10 @@ import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import com.avsystem.scex.validation.SymbolValidator._ import org.scalatest.funsuite.AnyFunSuite -import scala.reflect.{ClassTag, classTag} +import scala.reflect.{classTag, ClassTag} -/** - * Created: 17-09-2013 - * Author: ghik - */ +/** Created: 17-09-2013 Author: ghik + */ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { override protected def createCompiler = new XmlFriendlyJavaScexCompiler(new ScexSettings) @@ -22,14 +20,16 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { test("single quotes test") { val profile = createProfile(Nil) - val expr = compiler.getCompiledExpression[SimpleContext[Unit], String](profile, "'single quoted string'", template = false) + val expr = + compiler.getCompiledExpression[SimpleContext[Unit], String](profile, "'single quoted string'", template = false) assert("single quoted string" == expr.apply(SimpleContext(()))) } test("boolean expressions test") { val profile = createProfile(Nil) - val expr = compiler.getCompiledExpression[SimpleContext[Unit], Boolean](profile, "true or true and false", template = false) + val expr = + compiler.getCompiledExpression[SimpleContext[Unit], Boolean](profile, "true or true and false", template = false) assert(expr.apply(SimpleContext(()))) } @@ -45,7 +45,11 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { val acl = PredefinedAccessSpecs.basicOperations val expr = "#dafuq + 2345" try { - compiler.getCompiledExpression[SimpleContext[Unit], String](createProfile(acl, dynamicVariablesEnabled = false), expr, template = false) + compiler.getCompiledExpression[SimpleContext[Unit], String]( + createProfile(acl, dynamicVariablesEnabled = false), + expr, + template = false, + ) } catch { case CompilationFailedException(_, List(CompileError(source, column, msg))) => assert(source == expr) @@ -73,7 +77,7 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { profile = createProfile(acl, dynamicVariablesEnabled = dynamicVariablesEnabled), expression = expr, template = false, - variableTypes = Map("someDouble" -> TypeString[Double]) + variableTypes = Map("someDouble" -> TypeString[Double]), ) assert(180.0 == cexpr(dynamicVariablesEnabled = false)(context)) @@ -91,7 +95,7 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { profile = createProfile(acl, dynamicVariablesEnabled = dynamicVariablesEnabled), expression = expr, template = false, - variableTypes = Map("someDouble" -> TypeString[Double]) + variableTypes = Map("someDouble" -> TypeString[Double]), ) try { @@ -111,8 +115,12 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { val expr = "#someDouble.toDegrees" val context = new ClassTaggedContext context.setTypedVariable("someDouble", math.Pi)(classTag[Double]) - val cexpr = compiler.getCompiledExpression[ClassTaggedContext, Double](createProfile(acl), expr, template = false, - variableTypes = Map("someDouble" -> TypeString[Double])) + val cexpr = compiler.getCompiledExpression[ClassTaggedContext, Double]( + createProfile(acl), + expr, + template = false, + variableTypes = Map("someDouble" -> TypeString[Double]), + ) assert(180.0 == cexpr(context)) } @@ -120,8 +128,12 @@ class XmlFriendlyCompilerTest extends AnyFunSuite with CompilationTest { val acl = PredefinedAccessSpecs.basicOperations val expr = "#someDouble.toDegrees" assertMemberAccessForbidden { - compiler.getCompiledExpression[ClassTaggedContext, Double](createProfile(acl), expr, template = false, - variableTypes = Map("someDouble" -> TypeString[Double])) + compiler.getCompiledExpression[ClassTaggedContext, Double]( + createProfile(acl), + expr, + template = false, + variableTypes = Map("someDouble" -> TypeString[Double]), + ) } } diff --git a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslatorTest.scala b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslatorTest.scala index 5406451d..cabaceb5 100644 --- a/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslatorTest.scala +++ b/scex-core/src/test/scala/com/avsystem/scex/compiler/xmlfriendly/XmlFriendlyTranslatorTest.scala @@ -4,9 +4,7 @@ package compiler.xmlfriendly import com.google.common.io.ByteStreams import org.scalatest.funsuite.AnyFunSuite -/** - * Created: 23-04-2014 - * Author: ghik +/** Created: 23-04-2014 Author: ghik */ class XmlFriendlyTranslatorTest extends AnyFunSuite { @@ -17,15 +15,15 @@ class XmlFriendlyTranslatorTest extends AnyFunSuite { val translated = " _vars.lol" val pstr = translate(original) assert(translated == pstr.result) - assert(original.indices.map(pstr.positionMapping.apply) == - Seq(0, 2, 8, 9, 10)) - assert(translated.indices.map(pstr.positionMapping.reverse.apply) == - Seq(0, 0, 1, 1, 1, 1, 1, 1, 2, 3, 4)) + assert(original.indices.map(pstr.positionMapping.apply) == Seq(0, 2, 8, 9, 10)) + assert(translated.indices.map(pstr.positionMapping.reverse.apply) == Seq(0, 0, 1, 1, 1, 1, 1, 1, 2, 3, 4)) } test("variables in template test") { - assert("fuu #lol $$lol ${fuu} haha ${ _vars.dafuq + 5} ss" == - translate("fuu #lol $lol ${fuu} haha ${#dafuq + 5} ss", template = true).result) + assert( + "fuu #lol $$lol ${fuu} haha ${ _vars.dafuq + 5} ss" == + translate("fuu #lol $lol ${fuu} haha ${#dafuq + 5} ss", template = true).result + ) } test("negated variable test") { @@ -63,10 +61,8 @@ class XmlFriendlyTranslatorTest extends AnyFunSuite { val translated = "${`type`}" val pstr = translate(original) assert(translated == pstr.result) - assert(original.indices.map(pstr.positionMapping.apply) == - Seq(0, 1, 3, 4, 5, 6, 8)) - assert(translated.indices.map(pstr.positionMapping.reverse.apply) == - Seq(0, 1, 2, 2, 3, 4, 5, 5, 6)) + assert(original.indices.map(pstr.positionMapping.apply) == Seq(0, 1, 3, 4, 5, 6, 8)) + assert(translated.indices.map(pstr.positionMapping.reverse.apply) == Seq(0, 1, 2, 2, 3, 4, 5, 5, 6)) } test("unused scala keyword selection test") { diff --git a/scex-macros/src/main/scala/com/avsystem/scex/Macros.scala b/scex-macros/src/main/scala/com/avsystem/scex/Macros.scala index 88cc1fd4..d6d132f7 100644 --- a/scex-macros/src/main/scala/com/avsystem/scex/Macros.scala +++ b/scex-macros/src/main/scala/com/avsystem/scex/Macros.scala @@ -4,10 +4,8 @@ import com.avsystem.scex.util.MacroUtils import scala.reflect.macros.blackbox -/** - * Created: 18-11-2013 - * Author: ghik - */ +/** Created: 18-11-2013 Author: ghik + */ class Macros(val c: blackbox.Context) extends MacroUtils { lazy val universe: c.universe.type = c.universe @@ -34,7 +32,7 @@ class Macros(val c: blackbox.Context) extends MacroUtils { case _ => false } - assert(parts forall isStringLiteral) + assert(parts.forall(isStringLiteral)) assert(parts.size == args.size + 1) val resultType = weakTypeOf[T] @@ -86,7 +84,10 @@ class Macros(val c: blackbox.Context) extends MacroUtils { } else if (typeOf[String] <:< resultType) { reifyConcatenation(parts, argTrees) } else { - c.abort(soleArgTree.pos, s"This template (type ${soleArgTree.tpe.widen}) cannot represent value of type $resultType") + c.abort( + soleArgTree.pos, + s"This template (type ${soleArgTree.tpe.widen}) cannot represent value of type $resultType", + ) } } else if (typeOf[String] <:< resultType) { diff --git a/scex-macros/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoParser.scala b/scex-macros/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoParser.scala index 6acb849e..6565c432 100644 --- a/scex-macros/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoParser.scala +++ b/scex-macros/src/main/scala/com/avsystem/scex/symboldsl/SymbolInfoParser.scala @@ -7,9 +7,7 @@ import scala.collection.mutable.ListBuffer import scala.reflect.internal.Flags import scala.reflect.macros.blackbox -/** - * Author: ghik - * Created: 11/14/14. +/** Author: ghik Created: 11/14/14. */ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUtils { lazy val universe: c.universe.type = c.universe @@ -53,13 +51,12 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt // transforms list of expressions of type List[SymbolInfo[T]] to single expression // of type List[SymbolInfo[T]] that represents flattened original list of lists - def reifyFlattenLists(listExprs: List[Tree]) = { + def reifyFlattenLists(listExprs: List[Tree]) = q""" val b = new $CollectionPkg.mutable.ListBuffer[$SymbolInfoCls[$PayloadType]] ..${listExprs.map(listExpr => q"b ++= $listExpr")} b.result() """ - } def reifyRuntimeClassOpt(tpe: Type): Tree = if (tpe == NoType || isJavaStaticType(tpe)) { @@ -71,34 +68,36 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt def existentialSymbol(name: String, typeSignature: Type) = { val typeName = TypeName(name) val flags = internal.reificationSupport.FlagsRepr(Flags.DEFERRED | Flags.EXISTENTIAL) - val result = internal.reificationSupport.newNestedSymbol(rootMirror.RootClass, typeName, NoPosition, flags, isClass = false) + val result = + internal.reificationSupport.newNestedSymbol(rootMirror.RootClass, typeName, NoPosition, flags, isClass = false) internal.reificationSupport.setInfo(result, typeSignature) result } - /** - * Translates this type so that all existential types in this type do not refer to the defining class, - * as they do by default. Heavy wizardry. - * - * The problem is that when you reify an existential type (with `c.reifyType`), for example `Set[_]`, the - * wildcard is reified as a Symbol whose owner is the class that used that existential type. - * This effectively means that the definition of existential type refers the class that used it. - * This means that when the type is finally evaluated in some universe, things will blow up if that class is - * not visible to that universe. - * - * For example, this is exactly what happens if you use some existential type in the SymbolValidator DSL and - * the symbol validator is compiled at runtime using `compileSymbolValidator` method of ScexCompiler. That dynamically - * compiled class is not visible to the Scala compiler through classpath and when it tries to evaluate the reified - * type, we have a nice scala.reflect.internal.MissingRequirementError in our face. - */ + /** Translates this type so that all existential types in this type do not refer to the defining class, as they do by + * default. Heavy wizardry. + * + * The problem is that when you reify an existential type (with `c.reifyType`), for example `Set[_]`, the wildcard is + * reified as a Symbol whose owner is the class that used that existential type. This effectively means that the + * definition of existential type refers the class that used it. This means that when the type is finally evaluated + * in some universe, things will blow up if that class is not visible to that universe. + * + * For example, this is exactly what happens if you use some existential type in the SymbolValidator DSL and the + * symbol validator is compiled at runtime using `compileSymbolValidator` method of ScexCompiler. That dynamically + * compiled class is not visible to the Scala compiler through classpath and when it tries to evaluate the reified + * type, we have a nice scala.reflect.internal.MissingRequirementError in our face. + */ def detachExistentials(tpe: Type) = tpe.map { case ExistentialType(quantified, underlying) => val rootSymbol = rootMirror.RootClass - val symbolMapping = quantified.collect { - case oldSymbol if oldSymbol.owner != rootSymbol => - (oldSymbol, existentialSymbol(oldSymbol.fullName.replace(".", "_"), oldSymbol.typeSignature)) - }.toMap.withDefault(identity) + val symbolMapping = quantified + .collect { + case oldSymbol if oldSymbol.owner != rootSymbol => + (oldSymbol, existentialSymbol(oldSymbol.fullName.replace(".", "_"), oldSymbol.typeSignature)) + } + .toMap + .withDefault(identity) val newQuantified = quantified.map(symbolMapping) val newUnderlying = underlying.map { @@ -111,10 +110,9 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt case subTpe => subTpe } - /** - * Handles @plus and @minus type annotations. - * For example `java.util.List[Number@plus]` is translated to `java.util.List[_ <: Number]` - */ + /** Handles @plus and @minus type annotations. For example `java.util.List[Number@plus]` is translated to + * `java.util.List[_ <: Number]` + */ def existentialize(tpe: Type) = { object PlusOrMinus { def unapply(ann: Annotation) = @@ -174,17 +172,19 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt """ def unwrapConvertedPrefix(prefix: Tree) = prefix match { - case TypeApply(Select(convTree@ImplicitlyConverted(actualPrefix, fun), TermName("as")), List(_)) - if hasType(convTree, DirectWildcardSelectorType) => actualPrefix + case TypeApply(Select(convTree @ ImplicitlyConverted(actualPrefix, fun), TermName("as")), List(_)) + if hasType(convTree, DirectWildcardSelectorType) => + actualPrefix case _ => prefix } def checkPrefix(required: Option[(Symbol, Type)], prefix: Tree) = (required, prefix) match { case (Some((requiredSymbol, requiredTpe)), Ident(_)) - if prefix.symbol == requiredSymbol && prefix.tpe <:< requiredTpe => + if prefix.symbol == requiredSymbol && prefix.tpe <:< requiredTpe => requiredTpe - case (None, _) if prefix.symbol.isModule || - (prefix.symbol.isStatic && prefix.symbol.isMethod && prefix.symbol.asMethod.isStable) => + case (None, _) + if prefix.symbol.isModule || + (prefix.symbol.isStatic && prefix.symbol.isMethod && prefix.symbol.asMethod.isStable) => prefix.tpe case _ => c.abort(prefix.pos, "Bad prefix: " + show(prefix)) @@ -199,7 +199,12 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt c.abort(tpeTree.pos, "Bad symbol specification syntax:") } - case class ParsedWildcardSelector(prefixTpe: Type, payloadTree: Tree, scope: List[TermSymbol], implConv: Option[(Tree, Type)]) { + case class ParsedWildcardSelector( + prefixTpe: Type, + payloadTree: Tree, + scope: List[TermSymbol], + implConv: Option[(Tree, Type)], + ) { def filterScope(pred: TermSymbol => Boolean) = copy(scope = scope.filter(pred)) @@ -226,7 +231,8 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt lazy val InvalidParsedWildcardSelector = ParsedWildcardSelector(NoType, EmptyTree, Nil, None) - def parseWildcardSelector(requiredPrefix: Option[(Symbol, Type)], payloadTree: Tree, tree: Tree): ParsedWildcardSelector = tree match { + def parseWildcardSelector(requiredPrefix: Option[(Symbol, Type)], payloadTree: Tree, tree: Tree) + : ParsedWildcardSelector = tree match { // prefix implicitly converted to DirectWildcardSelector case ImplicitlyConverted(prefix, _) if hasType(tree, DirectWildcardSelectorType) => val tpe = checkPrefix(requiredPrefix, unwrapConvertedPrefix(prefix)) @@ -234,7 +240,7 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt // SymbolValidator.allStatic[T] case TypeApply(Select(symbolDslModule, TermName("allStatic")), List(tpeTree)) - if hasType(symbolDslModule, dslObjectType) && isJavaClass(tpeTree.symbol) => + if hasType(symbolDslModule, dslObjectType) && isJavaClass(tpeTree.symbol) => val tpeWithStatics = tpeTree.symbol.companion.typeSignature ParsedWildcardSelector(tpeWithStatics, payloadTree, accessibleMembers(tpeWithStatics), None) @@ -245,15 +251,16 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt // .implicitlyAs[T] case TypeApply(Select(prefix, TermName("implicitlyAs")), List(implicitTpeTree)) - if hasType(prefix, DirectWildcardSelectorType) => + if hasType(prefix, DirectWildcardSelectorType) => val prefixTpe = parseWildcardSelector(requiredPrefix, payloadTree, prefix).prefixTpe val implicitTpe = implicitTpeTree.tpe - val implConv = stripTypeApply(c.inferImplicitView(EmptyTree, prefixTpe, implicitTpe, - silent = true, withMacrosDisabled = false, tree.pos)) + val implConv = stripTypeApply( + c.inferImplicitView(EmptyTree, prefixTpe, implicitTpe, silent = true, withMacrosDisabled = false, tree.pos) + ) - //TODO: filter out members that already exist in original type + // TODO: filter out members that already exist in original type if (isGlobalImplicitConversion(implConv)) { val newScope = accessibleMembers(implicitTpe).filterNot(isConstructor) ParsedWildcardSelector(prefixTpe, payloadTree, newScope, Some((implConv, implicitTpe))) @@ -264,7 +271,7 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt // .constructorWithSignature() case Apply(Select(prefix, TermName("constructorWithSignature")), List(Literal(Constant(signature: String)))) - if hasType(prefix, DirectWildcardSelectorType) => + if hasType(prefix, DirectWildcardSelectorType) => val prevSelector = parseWildcardSelector(requiredPrefix, payloadTree, prefix) prevSelector.scope.find(p => isConstructor(p) && p.typeSignature.toString == signature) match { @@ -274,8 +281,11 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt val availableSignatures = prevSelector.scope.collect { case member if isConstructor(member) => member.typeSignature.toString } - c.error(tree.pos, s"Type ${prevSelector.prefixTpe.widen} has no constructor with signature $signature\n" + - s"Signatures of available constructors are: ${availableSignatures.mkString(", ")}") + c.error( + tree.pos, + s"Type ${prevSelector.prefixTpe.widen} has no constructor with signature $signature\n" + + s"Signatures of available constructors are: ${availableSignatures.mkString(", ")}", + ) InvalidParsedWildcardSelector } @@ -298,11 +308,15 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt // .members case Select(prefix, TermName("members")) if hasType(prefix, MemberSubsetsType) => - parseWildcardSelector(requiredPrefix, payloadTree, prefix).filterScopeNot(m => isConstructor(m) || isFromToplevelType(m)) + parseWildcardSelector(requiredPrefix, payloadTree, prefix).filterScopeNot(m => + isConstructor(m) || isFromToplevelType(m) + ) // .membersNamed. - case Apply(Select(Select(prefix, TermName("membersNamed")), TermName("selectDynamic")), List(Literal(Constant(name: String)))) - if hasType(prefix, MemberSubsetsType) => + case Apply( + Select(Select(prefix, TermName("membersNamed")), TermName("selectDynamic")), + List(Literal(Constant(name: String))), + ) if hasType(prefix, MemberSubsetsType) => val termName = TermName(name).encodedName val result = parseWildcardSelector(requiredPrefix, payloadTree, prefix).filterScope(_.name == termName) @@ -312,8 +326,7 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt } else result // .membersNamed() - case Apply(Select(prefix, TermName("membersNamed")), nameTrees) - if hasType(prefix, MemberSubsetsType) => + case Apply(Select(prefix, TermName("membersNamed")), nameTrees) if hasType(prefix, MemberSubsetsType) => val names = nameTrees.collect { case LiteralString(name) => name @@ -322,11 +335,13 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt "" }.toSet - val result = parseWildcardSelector(requiredPrefix, payloadTree, prefix).filterScope(names contains _.name.decodedName.toString) - val absentMembers = names diff result.scope.map(_.name.decodedName.toString).toSet + val result = parseWildcardSelector(requiredPrefix, payloadTree, prefix).filterScope( + names contains _.name.decodedName.toString + ) + val absentMembers = names.diff(result.scope.map(_.name.decodedName.toString).toSet) if (absentMembers.nonEmpty) { - absentMembers.foreach { - name => c.error(tree.pos, s"No member named $name found in type ${result.sourceTpe.widen}") + absentMembers.foreach { name => + c.error(tree.pos, s"No member named $name found in type ${result.sourceTpe.widen}") } InvalidParsedWildcardSelector } else result @@ -357,7 +372,7 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt reifyFlattenLists((stats :+ finalExpr).map(extractSymbols(requiredPrefix, payloadTree, _))) case Apply(Select(ImplicitlyConverted(inner, _), DecodedTermName("-->")), List(newPayloadTree)) - if hasType(body, AttachedPayloadType) => + if hasType(body, AttachedPayloadType) => extractSymbols(requiredPrefix, newPayloadTree, inner) case _ if body.tpe =:= CompleteWildcardSelectorType => @@ -366,8 +381,13 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt case NewInstance(tpeTree, _) => reifySymbolInfo(checkNewInstanceTpe(requiredPrefix, tpeTree), payloadTree, body.symbol, None) - case Select(apply@ImplicitlyConverted(prefix, fun), _) => - reifySymbolInfo(checkPrefix(requiredPrefix, unwrapConvertedPrefix(prefix)), payloadTree, body.symbol, Some(stripTypeApply(fun))) + case Select(apply @ ImplicitlyConverted(prefix, fun), _) => + reifySymbolInfo( + checkPrefix(requiredPrefix, unwrapConvertedPrefix(prefix)), + payloadTree, + body.symbol, + Some(stripTypeApply(fun)), + ) case Select(prefix, _) => reifySymbolInfo(checkPrefix(requiredPrefix, unwrapConvertedPrefix(prefix)), payloadTree, body.symbol, None) @@ -381,8 +401,8 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt case Typed(inner, _) => extractSymbols(requiredPrefix, payloadTree, inner) - case Function(List(valdef@ValDef(_, _, prefixTpeTree, _)), actualBody) - if internal.attachments(body).get[SymbolDslOnMark.type].isDefined => + case Function(List(valdef @ ValDef(_, _, prefixTpeTree, _)), actualBody) + if internal.attachments(body).get[SymbolDslOnMark.type].isDefined => extractSymbols(Some((valdef.symbol, prefixTpeTree.tpe)), payloadTree, actualBody) @@ -399,9 +419,8 @@ abstract class SymbolInfoParser[C <: blackbox.Context](val c: C) extends MacroUt def extractSymbolInfos(tree: Tree): Tree = { val symbolInfos = extractSymbols(None, defaultPayload, tree) - val typeInfoDefs = typeInfos.iterator.map { - case (typeKey, termName) => - ValDef(Modifiers(), termName, TypeTree(), reifyTypeInfo(typeKey.tpe)) + val typeInfoDefs = typeInfos.iterator.map { case (typeKey, termName) => + ValDef(Modifiers(), termName, TypeTree(), reifyTypeInfo(typeKey.tpe)) }.toList Block(typeInfoDefs, symbolInfos) diff --git a/scex-macros/src/main/scala/com/avsystem/scex/util/MacroUtils.scala b/scex-macros/src/main/scala/com/avsystem/scex/util/MacroUtils.scala index b483c9b4..4a753757 100644 --- a/scex-macros/src/main/scala/com/avsystem/scex/util/MacroUtils.scala +++ b/scex-macros/src/main/scala/com/avsystem/scex/util/MacroUtils.scala @@ -26,8 +26,8 @@ trait MacroUtils extends CrossMacroUtils { lazy val templateInterpolationsType: Type = scexClassType("compiler.TemplateInterpolations") lazy val splicerType: Type = scexClassType("compiler.TemplateInterpolations.Splicer") - lazy val any2stringadd: Symbol = symAlternatives(typeOf[Predef.type].member(TermName("any2stringadd"))) - .find(_.isMethod).getOrElse(NoSymbol) + lazy val any2stringadd: Symbol = + symAlternatives(typeOf[Predef.type].member(TermName("any2stringadd"))).find(_.isMethod).getOrElse(NoSymbol) @nowarn("msg=deprecated") lazy val stringAddPlus: Symbol = typeOf[any2stringadd[_]].member(TermName("+").encodedName) lazy val stringConcat: Symbol = typeOf[String].member(TermName("+").encodedName) @@ -45,7 +45,8 @@ trait MacroUtils extends CrossMacroUtils { lazy val AdapterWrappedName: TermName = TermName("_wrapped") lazy val toplevelSymbols: Set[Symbol] = Set(typeOf[Any], typeOf[AnyRef], typeOf[AnyVal]).map(_.typeSymbol) - lazy val standardStringInterpolations: Set[Symbol] = Set("s", "raw").map(name => typeOf[StringContext].member(TermName(name))) + lazy val standardStringInterpolations: Set[Symbol] = + Set("s", "raw").map(name => typeOf[StringContext].member(TermName(name))) lazy val getClassSymbol: Symbol = typeOf[Any].member(TermName("getClass")) object DecodedTermName { @@ -71,7 +72,8 @@ trait MacroUtils extends CrossMacroUtils { object ImplicitlyConverted { def unapply(tree: Tree): Option[(Tree, Tree)] = tree match { case Apply(fun, List(prefix)) - if isGlobalImplicitConversion(fun) && (tree.pos == NoPosition || prefix.pos == NoPosition || tree.pos == prefix.pos) => + if isGlobalImplicitConversion(fun) && + (tree.pos == NoPosition || prefix.pos == NoPosition || tree.pos == prefix.pos) => Some((prefix, fun)) case _ => None @@ -146,8 +148,8 @@ trait MacroUtils extends CrossMacroUtils { object SelectDynamic { def unapply(tree: Tree): Option[(Tree, String)] = tree match { - case Apply(Select(qual, TermName("selectDynamic")), List(lit@Literal(Constant(name: String)))) - if qual.tpe != null && qual.tpe <:< dynamicTpe && lit.pos.isTransparent => + case Apply(Select(qual, TermName("selectDynamic")), List(lit @ Literal(Constant(name: String)))) + if qual.tpe != null && qual.tpe <:< dynamicTpe && lit.pos.isTransparent => Some((qual, name)) case _ => None } @@ -234,8 +236,7 @@ trait MacroUtils extends CrossMacroUtils { case _ => throw new IllegalArgumentException("This tree does not represent simple path: " + showRaw(tree)) } - /** - * Is this tree a path that starts with package and goes through stable symbols (vals and objects)? + /** Is this tree a path that starts with package and goes through stable symbols (vals and objects)? * * @return */ @@ -248,7 +249,7 @@ trait MacroUtils extends CrossMacroUtils { def isGlobalImplicitConversion(tree: Tree): Boolean = tree match { case TypeApply(prefix, _) => isGlobalImplicitConversion(prefix) - //TODO handle apply method on implicit function values + // TODO handle apply method on implicit function values case Select(prefix, name) => tree.symbol.isMethod && tree.symbol.isImplicit && isStableGlobalPath(prefix) case _ => false @@ -300,8 +301,8 @@ trait MacroUtils extends CrossMacroUtils { val name = symbol.name.decodedName.toString !isGetClass(methodSymbol) && methodSymbol.paramLists == List(List()) && methodSymbol.typeParams.isEmpty && - (BeanGetterNamePattern.pattern.matcher(name).matches || - BooleanBeanGetterNamePattern.pattern.matcher(name).matches && isBooleanType(methodSymbol.returnType)) + (BeanGetterNamePattern.pattern.matcher(name).matches || + BooleanBeanGetterNamePattern.pattern.matcher(name).matches && isBooleanType(methodSymbol.returnType)) } def isParameterless(s: TermSymbol): Boolean = @@ -339,16 +340,17 @@ trait MacroUtils extends CrossMacroUtils { val name = symbol.name.decodedName.toString takesSingleParameter(methodSymbol) && methodSymbol.typeParams.isEmpty && - methodSymbol.returnType =:= typeOf[Unit] && - BeanSetterNamePattern.pattern.matcher(name).matches + methodSymbol.returnType =:= typeOf[Unit] && BeanSetterNamePattern.pattern.matcher(name).matches } - /** - * Accessible members include methods, modules, val/var setters and getters and Java fields. + /** Accessible members include methods, modules, val/var setters and getters and Java fields. */ def accessibleMembers(tpe: Type): List[TermSymbol] = - tpe.members.toList.collect { case s if s.isPublic && s.isTerm && - (s.isJava || (!s.asTerm.isVal && !s.asTerm.isVar)) && !s.isImplementationArtifact => s.asTerm + tpe.members.toList.collect { + case s + if s.isPublic && s.isTerm && (s.isJava || (!s.asTerm.isVal && !s.asTerm.isVar)) && + !s.isImplementationArtifact => + s.asTerm } def hasType(tree: Tree, tpe: Type): Boolean = @@ -373,8 +375,7 @@ trait MacroUtils extends CrossMacroUtils { nonBottomSymbolType(symbol) <:< profileObjectType def isFromProfileObject(symbol: Symbol): Boolean = - symbol != null && symbol != NoSymbol && - (isProfileObject(symbol) || isFromProfileObject(symbol.owner)) + symbol != null && symbol != NoSymbol && (isProfileObject(symbol) || isFromProfileObject(symbol.owner)) def isScexSynthetic(symbol: Symbol): Boolean = symbol != null && symbol != NoSymbol && @@ -386,8 +387,7 @@ trait MacroUtils extends CrossMacroUtils { def isBottom(tpe: Type): Boolean = tpe <:< definitions.NullTpe || tpe <:< definitions.NothingTpe - /** - * Is this symbol the 'wrapped' field of Java getter adapter? + /** Is this symbol the 'wrapped' field of Java getter adapter? */ def isAdapterWrappedMember(symbol: Symbol): Boolean = if (symbol != null && symbol.isTerm) { @@ -441,10 +441,11 @@ trait MacroUtils extends CrossMacroUtils { def annotations(sym: Symbol): List[Annotation] = { sym.info // force annotations - sym.annotations ++ (if (sym.isTerm) { - val tsym = sym.asTerm - if (tsym.isGetter) annotations(tsym.accessed) else Nil - } else Nil) + sym.annotations ++ + (if (sym.isTerm) { + val tsym = sym.asTerm + if (tsym.isGetter) annotations(tsym.accessed) else Nil + } else Nil) } def annotationsIncludingOverrides(sym: Symbol): List[Annotation] = @@ -460,7 +461,7 @@ trait MacroUtils extends CrossMacroUtils { } object MacroUtils { - def apply(u: Universe): MacroUtils {val universe: u.type} = + def apply(u: Universe): MacroUtils { val universe: u.type } = new MacroUtils { val universe: u.type = u } diff --git a/scex-macros/src/main/scala/com/avsystem/scex/util/TypeWrapper.scala b/scex-macros/src/main/scala/com/avsystem/scex/util/TypeWrapper.scala index 204a7bf4..2c66b42c 100644 --- a/scex-macros/src/main/scala/com/avsystem/scex/util/TypeWrapper.scala +++ b/scex-macros/src/main/scala/com/avsystem/scex/util/TypeWrapper.scala @@ -6,10 +6,9 @@ import java.{lang => jl, util => ju} import scala.collection.mutable.ListBuffer import scala.reflect.api.Universe -/** - * The purpose of this class is to have meaningful equals/hashCode semantics for Type objects - */ -class TypeWrapper(universeWithTpe: (u.type, u.Type) forSome {val u: Universe}) { +/** The purpose of this class is to have meaningful equals/hashCode semantics for Type objects + */ +class TypeWrapper(universeWithTpe: (u.type, u.Type) forSome { val u: Universe }) { private val u = universeWithTpe._1 private val tpe = universeWithTpe._2.asInstanceOf[u.Type] @@ -46,4 +45,4 @@ class TypeWrapper(universeWithTpe: (u.type, u.Type) forSome {val u: Universe}) { object TypeWrapper { def apply(u: Universe)(tpe: u.Type) = new TypeWrapper((u, tpe): (u.type, u.Type)) -} \ No newline at end of file +} diff --git a/scex-test/src/main/scala/AutoConvertTest.scala b/scex-test/src/main/scala/AutoConvertTest.scala index 1df2c17d..d24ac0c4 100644 --- a/scex-test/src/main/scala/AutoConvertTest.scala +++ b/scex-test/src/main/scala/AutoConvertTest.scala @@ -3,10 +3,8 @@ import com.avsystem.scex.util.Literal import scala.annotation.nowarn -/** - * Created: 30-05-2014 - * Author: ghik - */ +/** Created: 30-05-2014 Author: ghik + */ object AutoConvertTest { implicit final class stringAutoConvert(private val str: String) extends AnyVal { diff --git a/scex-test/src/main/scala/ExistentialCase.scala b/scex-test/src/main/scala/ExistentialCase.scala index faf0a084..35af99e8 100644 --- a/scex-test/src/main/scala/ExistentialCase.scala +++ b/scex-test/src/main/scala/ExistentialCase.scala @@ -5,10 +5,8 @@ import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import com.avsystem.scex.validation.{SymbolValidator, SyntaxValidator} import com.avsystem.scex.{ExpressionProfile, NamedSource} -/** - * Created: 04-12-2013 - * Author: ghik - */ +/** Created: 04-12-2013 Author: ghik + */ object ExistentialCase { def main(args: Array[String]): Unit = { val compiler = new XmlFriendlyJavaScexCompiler(new ScexSettings) @@ -17,11 +15,12 @@ object ExistentialCase { val syntaxValidator = SyntaxValidator.SimpleExpressions val symbolAttributes = SymbolAttributes(Nil) - val profile = new ExpressionProfile("test", syntaxValidator, symbolValidator, symbolAttributes, "", NamedSource("test", "")) + val profile = + new ExpressionProfile("test", syntaxValidator, symbolValidator, symbolAttributes, "", NamedSource("test", "")) - val completion = compiler.getCompleter[SimpleContext[Unit], Int](profile, template = true) - .getTypeCompletion("${'dafuq'.toInt}", 14) + val completion = + compiler.getCompleter[SimpleContext[Unit], Int](profile, template = true).getTypeCompletion("${'dafuq'.toInt}", 14) - completion.members foreach println + completion.members.foreach(println) } } diff --git a/scex-test/src/main/scala/MemoryTest.scala b/scex-test/src/main/scala/MemoryTest.scala index 9ad04827..3eb7b18c 100644 --- a/scex-test/src/main/scala/MemoryTest.scala +++ b/scex-test/src/main/scala/MemoryTest.scala @@ -28,8 +28,14 @@ object MemoryTest { ) val symbolAttributes = SymbolAttributes(Nil) - val profile = new ExpressionProfile("test", SyntaxValidator.SimpleExpressions, symbolValidator, - symbolAttributes, "", NamedSource("test", "")) + val profile = new ExpressionProfile( + "test", + SyntaxValidator.SimpleExpressions, + symbolValidator, + symbolAttributes, + "", + NamedSource("test", ""), + ) var i = 0 while (true) { diff --git a/scex-test/src/main/scala/Playground.scala b/scex-test/src/main/scala/Playground.scala index 52515ae8..b5801c3c 100644 --- a/scex-test/src/main/scala/Playground.scala +++ b/scex-test/src/main/scala/Playground.scala @@ -1,11 +1,8 @@ - import java.{lang => jl, util => ju} import scala.language.experimental.macros object Playground { - def main(args: Array[String]): Unit = { - - } + def main(args: Array[String]): Unit = {} } diff --git a/scex-test/src/main/scala/SymbolValidatorTests.scala b/scex-test/src/main/scala/SymbolValidatorTests.scala index 8bede71e..11f80856 100644 --- a/scex-test/src/main/scala/SymbolValidatorTests.scala +++ b/scex-test/src/main/scala/SymbolValidatorTests.scala @@ -2,13 +2,12 @@ import java.{lang => jl, util => ju} import com.avsystem.scex.validation.SymbolValidator._ - object SymbolValidatorTests { def main(args: Array[String]): Unit = { var specs: List[MemberAccessSpec] = null def printSpecs(): Unit = { - specs foreach println + specs.foreach(println) println() } diff --git a/scex-test/src/main/scala/Target.scala b/scex-test/src/main/scala/Target.scala index 35727799..9a2ade3d 100644 --- a/scex-test/src/main/scala/Target.scala +++ b/scex-test/src/main/scala/Target.scala @@ -33,4 +33,4 @@ object OTarget extends Target { def lol = 5 } -} \ No newline at end of file +} diff --git a/scex-test/src/main/scala/TemplateOptimizingPerformanceTest.scala b/scex-test/src/main/scala/TemplateOptimizingPerformanceTest.scala index 29f99033..b016e240 100644 --- a/scex-test/src/main/scala/TemplateOptimizingPerformanceTest.scala +++ b/scex-test/src/main/scala/TemplateOptimizingPerformanceTest.scala @@ -1,26 +1,26 @@ import com.avsystem.scex.compiler.ScexSettings import com.avsystem.scex.japi.XmlFriendlyJavaScexCompiler import com.avsystem.scex.presentation.SymbolAttributes -import com.avsystem.scex.util.{SimpleContext, PredefinedAccessSpecs} +import com.avsystem.scex.util.{PredefinedAccessSpecs, SimpleContext} import com.avsystem.scex.validation.{SymbolValidator, SyntaxValidator} import com.avsystem.scex.{ExpressionProfile, NamedSource} -/** - * Created: 04-11-2014 - * Author: ghik - */ +/** Created: 04-11-2014 Author: ghik + */ object TemplateOptimizingPerformanceTest { def main(args: Array[String]): Unit = { val settings = new ScexSettings settings.classfileDirectory.value = "scex_classes" val compiler = new XmlFriendlyJavaScexCompiler(settings) - val profile = new ExpressionProfile("test", + val profile = new ExpressionProfile( + "test", SyntaxValidator.SimpleExpressions, SymbolValidator(PredefinedAccessSpecs.basicOperations), SymbolAttributes(Nil), "", - NamedSource("empty", "")) + NamedSource("empty", ""), + ) val ctx = SimpleContext(()) compiler.getCompiledExpression[SimpleContext[Unit], String](profile, "${1+2}abc").apply(ctx) diff --git a/scex-test/src/main/scala/TypeConvertersTest.scala b/scex-test/src/main/scala/TypeConvertersTest.scala index b5c58de8..8162d509 100644 --- a/scex-test/src/main/scala/TypeConvertersTest.scala +++ b/scex-test/src/main/scala/TypeConvertersTest.scala @@ -1,12 +1,11 @@ import java.{lang => jl, util => ju} - object TypeConvertersTest { import scala.language.existentials def main(args: Array[String]): Unit = { - val clazz = classOf[TypedLol[T]#Dafuq[F] forSome {type T; type F}] + val clazz = classOf[TypedLol[T]#Dafuq[F] forSome { type T; type F }] import com.avsystem.scex.compiler.JavaTypeParsing._ diff --git a/scex-test/src/main/scala/ValidationTest.scala b/scex-test/src/main/scala/ValidationTest.scala index 30a491c8..0ef97d56 100644 --- a/scex-test/src/main/scala/ValidationTest.scala +++ b/scex-test/src/main/scala/ValidationTest.scala @@ -60,104 +60,93 @@ object ValidationTest { None Tuple2.apply _ - on { - anyRef: AnyRef => - anyRef == (_: AnyRef) - anyRef != (_: AnyRef) + on { anyRef: AnyRef => + anyRef == (_: AnyRef) + anyRef != (_: AnyRef) } - on { - tl: TypedLol[_] => - tl.toString + on { tl: TypedLol[_] => + tl.toString } - on { - d: (TypedLol[T]#Dafuq[_] forSome {type T}) => - d.getStuff + on { d: (TypedLol[T]#Dafuq[_] forSome { type T }) => + d.getStuff } - on { - s: String => - s.length - s.concat _ - s.matches _ - s.reverse - s.compare(_: String) + on { s: String => + s.length + s.concat _ + s.matches _ + s.reverse + s.compare(_: String) } - on { - sc: StringContext => - sc.all.membersNamed("s") + on { sc: StringContext => + sc.all.membersNamed("s") } - on { - al: ju.ArrayList[_] => - new ju.ArrayList(_: ju.Collection[_]) - al.all.members + on { al: ju.ArrayList[_] => + new ju.ArrayList(_: ju.Collection[_]) + al.all.members } - on { - any: Any => - any + (_: String) - any -> (_: Any) - any == (_: Any) - any != (_: Any) + on { any: Any => + any + (_: String) + any -> (_: Any) + any == (_: Any) + any != (_: Any) } - on { - a: A[Any@plus] => - a.costam _ - a.hoho _ - a.b() - a.multiParens(_: Int)(_: String, _: Float)(_: Nothing) - a.getClass - a.a_= _ + on { a: A[Any @plus] => + a.costam _ + a.hoho _ + a.b() + a.multiParens(_: Int)(_: String, _: Float)(_: Nothing) + a.getClass + a.a_= _ } - on { - i: Int => - i.implicitlyAs[RichInt].all.membersNamed.to - i.all.constructors - i.all.membersNamed("+") + on { i: Int => + i.implicitlyAs[RichInt].all.membersNamed.to + i.all.constructors + i.all.membersNamed("+") } - on { - jl: JavaLol => - jl.fuu - jl.isFoo + on { jl: JavaLol => + jl.fuu + jl.isFoo } Dyn.selectDynamic _ } ++ deny { - on { - any: Any => - any.equals _ - any.hashCode - any.## - any.getClass - any.asInstanceOf - any.isInstanceOf + on { any: Any => + any.equals _ + any.hashCode + any.## + any.getClass + any.asInstanceOf + any.isInstanceOf } - on { - anyRef: AnyRef => - anyRef.eq _ - anyRef.synchronized(_: Any) + on { anyRef: AnyRef => + anyRef.eq _ + anyRef.synchronized(_: Any) } } - //memberAccessSpecs foreach println + // memberAccessSpecs foreach println val syntaxValidator = new SyntaxValidator { def validateSyntax(u: Universe)(tree: u.Tree): (Boolean, List[u.Tree]) = { import u._ tree match { - case _: Block | _: Select | _: Apply | _: TypeApply | _: Ident | - _: If | _: Literal | _: New | _: This | _: Typed | _: TypTree => (true, tree.children) + case _: Block | _: Select | _: Apply | _: TypeApply | _: Ident | _: If | _: Literal | _: New | _: This | + _: Typed | _: TypTree => + (true, tree.children) case _ => (false, tree.children) } } @@ -181,7 +170,7 @@ object ValidationTest { val typedLol = new TL val dafuq = new typedLol.Dafuq[ju.ArrayList[CharSequence]] - type Typ = TypedLol[T]#Dafuq[F] forSome {type T <: TypedLol[T]; type F} + type Typ = TypedLol[T]#Dafuq[F] forSome { type T <: TypedLol[T]; type F } compiler.getCompiledExpression[SimpleContext[Any], String](profile, "\"lol\".toUpperCase", template = false) diff --git a/scex-test/src/main/scala/WildcardsTest.scala b/scex-test/src/main/scala/WildcardsTest.scala index 5152e84c..2f7454a4 100644 --- a/scex-test/src/main/scala/WildcardsTest.scala +++ b/scex-test/src/main/scala/WildcardsTest.scala @@ -1,4 +1,3 @@ - object WildcardsTest { def main(args: Array[String]): Unit = { import com.avsystem.scex.validation.SymbolValidator._ @@ -7,73 +6,73 @@ object WildcardsTest { on { sc: ScalaClass => sc.all.members } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.constructors } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.declared.members } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.introduced.members } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.beanGetters } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.beanSetters } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.scalaGetters } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.scalaSetters } - } foreach println + }.foreach(println) println() allow { on { sc: ScalaClass => sc.all.membersNamed.stuff } - } foreach println + }.foreach(println) println() allow { allStatic[String].members - } foreach println + }.foreach(println) println() allow { allStatic[String].membersNamed.valueOf - } foreach println + }.foreach(println) println() } } diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/Bytes.scala b/scex-util/src/main/scala/com/avsystem/scex/util/Bytes.scala index c3097e27..bb96f15b 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/Bytes.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/Bytes.scala @@ -43,7 +43,8 @@ final class Bytes(val bytes: Array[Byte]) extends Comparable[Bytes] { @Documentation("Decodes this sequence of bytes as string using given charset.") def decode(charset: String): String = - try new String(bytes, charset) catch { + try new String(bytes, charset) + catch { case e: UnsupportedEncodingException => throw new IllegalArgumentException(e) } diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/CommonExpressionUtils.scala b/scex-util/src/main/scala/com/avsystem/scex/util/CommonExpressionUtils.scala index 5c86d16b..90357a91 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/CommonExpressionUtils.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/CommonExpressionUtils.scala @@ -10,25 +10,21 @@ import java.text.ParseException import java.util.Date import scala.annotation.nowarn -/** - * Author: ghik - * Created: 16/10/15. +/** Author: ghik Created: 16/10/15. */ object CommonExpressionUtils { // a replacement for safe dereference operator (?.) and elvis operator (?:) @nowarn("msg=Implicit classes") implicit class any2qmark[A](value: => A) { def ?[B >: A](default: => B): B = { - val result = try value.opt catch { - case _: NullPointerException | - _: NoSuchElementException | - _: UnsupportedOperationException | - _: IndexOutOfBoundsException | - _: NumberFormatException | - _: IllegalArgumentException | - _: ParseException | - _: ExpressionRecoverableException => Opt.Empty - } + val result = + try value.opt + catch { + case _: NullPointerException | _: NoSuchElementException | _: UnsupportedOperationException | + _: IndexOutOfBoundsException | _: NumberFormatException | _: IllegalArgumentException | + _: ParseException | _: ExpressionRecoverableException => + Opt.Empty + } result getOrElse default } } @@ -96,9 +92,8 @@ object CommonExpressionUtils { val math = scala.math.`package` @Documentation("Access context variables") - def getVariable(name: String)(implicit ctx: SimpleContext[_]): String = { + def getVariable(name: String)(implicit ctx: SimpleContext[_]): String = ctx.getVariable(name) - } def bytes(bs: Byte*): Bytes = new Bytes(bs.toArray) diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/CommonSymbolValidators.scala b/scex-util/src/main/scala/com/avsystem/scex/util/CommonSymbolValidators.scala index b262f125..d62af5d1 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/CommonSymbolValidators.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/CommonSymbolValidators.scala @@ -15,7 +15,7 @@ object CommonSymbolValidators { import JavaCollectionExtensions._ allow { - on { c: JCollection[Any@plus] => + on { c: JCollection[Any @plus] => c.size c.contains _ c.containsAll _ @@ -28,16 +28,16 @@ object CommonSymbolValidators { list _ range(_: Int, _: Int, _: Int) range(_: Int, _: Int) - on { l: JList[Any@plus] => + on { l: JList[Any @plus] => l.get _ l.implicitlyAs[ListOps[Any]].all.members } set _ - on { s: JSet[Any@plus] => + on { s: JSet[Any @plus] => s.implicitlyAs[SetOps[Any]].all.members } map _ - on { m: JMap[Any@plus, Any@plus] => + on { m: JMap[Any @plus, Any @plus] => m.isEmpty m.size m.get _ @@ -48,17 +48,17 @@ object CommonSymbolValidators { m.implicitlyAs[MapOps[Any, Any]].all.introduced.members } entry _ - on { e: Entry[Any@plus, Any@plus] => + on { e: Entry[Any @plus, Any @plus] => e.key e.value e.withKey _ e.withValue _ e.toString } - on { c: JCollection[Entry[Any@plus, Any@plus]@plus] => + on { c: JCollection[Entry[Any @plus, Any @plus] @plus] => c.implicitlyAs[EntryCollectionOps[Any, Any]].all.members } - on { c: JCollection[(Any, Any)@plus] => + on { c: JCollection[(Any, Any) @plus] => c.implicitlyAs[PairCollectionOps[Any, Any]].all.members } diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/EnrichedDate.scala b/scex-util/src/main/scala/com/avsystem/scex/util/EnrichedDate.scala index d035ff2e..e31c73d4 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/EnrichedDate.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/EnrichedDate.scala @@ -85,4 +85,3 @@ object EnrichedZonedDate { def fromDate(date: Date, zone: ZoneId = Clock.systemDefaultZone().getZone) = new EnrichedZonedDate(ZonedDateTime.ofInstant(date.toInstant, zone)) } - diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/EscapedBytes.scala b/scex-util/src/main/scala/com/avsystem/scex/util/EscapedBytes.scala index 9888ea46..2054a203 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/EscapedBytes.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/EscapedBytes.scala @@ -7,7 +7,7 @@ object EscapedBytes { val sb = new StringBuilder bytes.foreach { case '\\' => sb ++= "\\\\" - case b if b > 0x1F && b < 0x7F => sb += b.toChar + case b if b > 0x1f && b < 0x7f => sb += b.toChar case b => sb ++= f"\\x$b%02x" } sb.result() @@ -17,22 +17,24 @@ object EscapedBytes { val baos = new ByteArrayOutputStream def loop(it: Iterator[Char]): Unit = if (it.hasNext) { it.next() match { - case '\\' => it.next() match { - case 'x' => - def readDigit(): Int = if (it.hasNext) it.next() match { - case d if d >= '0' && d <= '9' => d - '0' - case d if d >= 'A' && d <= 'F' => d - 'A' + 10 - case d if d >= 'a' && d <= 'f' => d - 'a' + 10 - case c => throw new IllegalArgumentException(s"Expected hex digit, got character: $c") - } else throw new IllegalArgumentException(s"Expected hex digit, got end of string") - var byte = readDigit() * 16 - byte += readDigit() - baos.write(byte) - case '\\' => baos.write('\\') - case c => - throw new IllegalArgumentException(s"Invalid escape character: $c, only \\ and hex escapes are allowed") - } - case c if c > 0x1F && c < 0x7F => + case '\\' => + it.next() match { + case 'x' => + def readDigit(): Int = if (it.hasNext) it.next() match { + case d if d >= '0' && d <= '9' => d - '0' + case d if d >= 'A' && d <= 'F' => d - 'A' + 10 + case d if d >= 'a' && d <= 'f' => d - 'a' + 10 + case c => throw new IllegalArgumentException(s"Expected hex digit, got character: $c") + } + else throw new IllegalArgumentException(s"Expected hex digit, got end of string") + var byte = readDigit() * 16 + byte += readDigit() + baos.write(byte) + case '\\' => baos.write('\\') + case c => + throw new IllegalArgumentException(s"Invalid escape character: $c, only \\ and hex escapes are allowed") + } + case c if c > 0x1f && c < 0x7f => baos.write(c) case c => throw new IllegalArgumentException(s"Invalid character in binary representation: $c") @@ -43,4 +45,3 @@ object EscapedBytes { baos.toByteArray } } - diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/ExpressionRecoverableException.scala b/scex-util/src/main/scala/com/avsystem/scex/util/ExpressionRecoverableException.scala index 0781e104..71951482 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/ExpressionRecoverableException.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/ExpressionRecoverableException.scala @@ -1,7 +1,6 @@ package com.avsystem.scex.util -/** - * If some exception extends this trait, it may be caught and recovered from using `?` operator in expressions. - * See [[CommonExpressionUtils.any2qmark.?]] +/** If some exception extends this trait, it may be caught and recovered from using `?` operator in expressions. See + * [[CommonExpressionUtils.any2qmark.?]] */ trait ExpressionRecoverableException extends Throwable diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/JavaCollectionExtensions.scala b/scex-util/src/main/scala/com/avsystem/scex/util/JavaCollectionExtensions.scala index 90b91439..715ae940 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/JavaCollectionExtensions.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/JavaCollectionExtensions.scala @@ -3,16 +3,14 @@ package com.avsystem.scex.util import com.avsystem.commons.jiop.JavaInterop._ import com.google.common.collect.{Collections2, Lists, Sets} -/** - * Java collection API extensions for SCEX expressions. +/** Java collection API extensions for SCEX expressions. */ object JavaCollectionExtensions { private type GFunction[F, T] = com.google.common.base.Function[F, T] private type JMapEntry[K, V] = java.util.Map.Entry[K, V] implicit final class CollectionOps[A](private val coll: JCollection[A]) extends AnyVal { - def ++(other: JCollection[A]): JCollection[A] = - (coll.asScala ++ other.asScala).asJavaCollection + def ++(other: JCollection[A]): JCollection[A] = (coll.asScala ++ other.asScala).asJavaCollection def filter(p: A => Boolean): JCollection[A] = coll.asScala.filter(p).asJavaCollection @@ -91,8 +89,7 @@ object JavaCollectionExtensions { } implicit final class ListOps[A](private val list: JList[A]) extends AnyVal { - def ++(other: JList[A]): JList[A] = - (list.asScala ++ other.asScala).asJava + def ++(other: JList[A]): JList[A] = (list.asScala ++ other.asScala).asJava def filter(p: A => Boolean): JList[A] = list.asScala.filter(p).asJava @@ -135,7 +132,7 @@ object JavaCollectionExtensions { } def slice(from: Int, until: Int): JList[A] = - list.subList(0 max from min list.size, 0 max until min list.size) + list.subList(0.max(from).min(list.size), 0.max(until).min(list.size)) def sorted(implicit ord: Ordering[A]): JList[A] = list.asScala.sorted.asJava @@ -148,8 +145,7 @@ object JavaCollectionExtensions { } implicit final class SetOps[A](private val set: JSet[A]) extends AnyVal { - def ++(other: JSet[A]): JSet[A] = - (set.asScala ++ other.asScala).asJava + def ++(other: JSet[A]): JSet[A] = (set.asScala ++ other.asScala).asJava def filter(p: A => Boolean): JSet[A] = set.asScala.filter(p).asJava @@ -158,10 +154,10 @@ object JavaCollectionExtensions { set ++ other def intersect(other: JSet[A]): JSet[A] = - (set.asScala intersect other.asScala).asJava + (set.asScala.intersect(other.asScala)).asJava def diff(other: JSet[A]): JSet[A] = - (set.asScala diff other.asScala).asJava + (set.asScala.diff(other.asScala)).asJava } final case class Entry[K, V](key: K, value: V) { @@ -178,8 +174,7 @@ object JavaCollectionExtensions { } implicit final class MapOps[K, V](protected val map: JMap[K, V]) extends AnyVal with MapOpsExtended[K, V] { - def ++(other: JMap[K, V]): JMap[K, V] = - (map.asScala ++ other.asScala).asJava + def ++(other: JMap[K, V]): JMap[K, V] = (map.asScala ++ other.asScala).asJava def apply(key: K): V = map.get(key) @@ -191,10 +186,12 @@ object JavaCollectionExtensions { } def entries: JCollection[Entry[K, V]] = - Collections2.transform(map.entrySet, + Collections2.transform( + map.entrySet, new GFunction[JMapEntry[K, V], Entry[K, V]] { def apply(e: JMapEntry[K, V]): Entry[K, V] = Entry(e.getKey, e.getValue) - }) + }, + ) def filter(p: Entry[K, V] => Boolean): JMap[K, V] = map.asScala.iterator.filter(e => p(Entry(e._1, e._2))).toJMap diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/StringMiscOps.scala b/scex-util/src/main/scala/com/avsystem/scex/util/StringMiscOps.scala index 5bcb5fef..b53800a7 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/StringMiscOps.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/StringMiscOps.scala @@ -16,25 +16,34 @@ import org.apache.commons.codec.digest.{DigestUtils, HmacAlgorithms, HmacUtils} import org.apache.commons.lang3.StringUtils final class StringMiscOps(private val wrapped: String) extends AnyVal { - @Documentation("Converts this string to date assuming it is a date in the yyyy.MM.dd HH:mm:ss format " + - "or a number of milliseconds since 1970.01.01 00:00:00.") - def toDate: JDate = try CommonDateFormat.get.parse(wrapped) catch { - case _: ParseException => try new JDate(wrapped.toLong) catch { - case _: NumberFormatException => throw new IllegalArgumentException(s"Cannot parse date: $wrapped") - } + @Documentation( + "Converts this string to date assuming it is a date in the yyyy.MM.dd HH:mm:ss format " + + "or a number of milliseconds since 1970.01.01 00:00:00." + ) + def toDate: JDate = try CommonDateFormat.get.parse(wrapped) + catch { + case _: ParseException => + try new JDate(wrapped.toLong) + catch { + case _: NumberFormatException => throw new IllegalArgumentException(s"Cannot parse date: $wrapped") + } } - @Documentation("Converts this string to date by parsing it according to the specified `format` " + - "defined with Java SimpleDateFormat. " + - "Example format: yyyy.MM.dd HH:mm:ss.") - def toDate(format: String): JDate = try new SimpleDateFormat(format).parse(wrapped) catch { + @Documentation( + "Converts this string to date by parsing it according to the specified `format` " + + "defined with Java SimpleDateFormat. " + "Example format: yyyy.MM.dd HH:mm:ss." + ) + def toDate(format: String): JDate = try new SimpleDateFormat(format).parse(wrapped) + catch { case _: ParseException => throw new IllegalArgumentException(s"Cannot parse date $wrapped using format $format") } - @Documentation("Converts this string to date by parsing it according to specified date `format` and `timezone`. " + - "Example format: yyyy.MM.dd HH:mm:ss. Example timeZone: GMT+2. " + - "Date format as per Java SimpleDateFormat.") + @Documentation( + "Converts this string to date by parsing it according to specified date `format` and `timezone`. " + + "Example format: yyyy.MM.dd HH:mm:ss. Example timeZone: GMT+2. " + + "Date format as per Java SimpleDateFormat." + ) def toDate(format: String, timeZone: String): JDate = try { val formatter = new SimpleDateFormat(format) formatter.setTimeZone(TimeZone.getTimeZone(timeZone)) @@ -44,13 +53,18 @@ final class StringMiscOps(private val wrapped: String) extends AnyVal { throw new IllegalArgumentException(e) } - @Documentation("Splits this string into a list of strings using given separator. " + - "Resulting parts are not whitespace-trimmed and blank parts are not filtered out.") + @Documentation( + "Splits this string into a list of strings using given separator. " + + "Resulting parts are not whitespace-trimmed and blank parts are not filtered out." + ) def splitBy(separator: String): JList[String] = java.util.Arrays.asList(wrapped.split(Pattern.quote(separator)): _*) - @Documentation("Splits this string into a list of strings using given separator. " + - "Resulting parts are whitespace-trimmed and blank parts are returned as empty strings.") - def splitByTrim(separator: String): JList[String] = Lists.newArrayList(Splitter.on(separator).trimResults.split(wrapped)) + @Documentation( + "Splits this string into a list of strings using given separator. " + + "Resulting parts are whitespace-trimmed and blank parts are returned as empty strings." + ) + def splitByTrim(separator: String): JList[String] = + Lists.newArrayList(Splitter.on(separator).trimResults.split(wrapped)) @Documentation("Assumes this string is a hexadecimal number and converts it to a decimal number.") def parseHex: Long = java.lang.Long.parseLong(wrapped, 16) @@ -71,7 +85,9 @@ final class StringMiscOps(private val wrapped: String) extends AnyVal { def ensureEnd(postfix: String): String = if (wrapped.endsWith(postfix)) wrapped else wrapped + postfix - @Documentation("Decodes this string assuming it contains escaped arbitrary bytes (backslash and non-ASCII bytes are escaped).") + @Documentation( + "Decodes this string assuming it contains escaped arbitrary bytes (backslash and non-ASCII bytes are escaped)." + ) def decodeEscapedBytes = new Bytes(EscapedBytes.parse(wrapped)) @Documentation("Assumes this string is a BASE64 encoding of another string and decodes it using UTF-8.") @@ -87,13 +103,15 @@ final class StringMiscOps(private val wrapped: String) extends AnyVal { def encodeHex: String = Hex.encodeHexString(wrapped.getBytes(StandardCharsets.UTF_8)) @Documentation("Decodes this string assuming it contains hexadecimal encoding of UTF-8 bytes of another string.") - def decodeHexString: String = try new String(Hex.decodeHex(wrapped.toCharArray), StandardCharsets.UTF_8) catch { + def decodeHexString: String = try new String(Hex.decodeHex(wrapped.toCharArray), StandardCharsets.UTF_8) + catch { case e: DecoderException => throw new IllegalArgumentException(e) } @Documentation("Decodes this string assuming it contains hexadecimal encoding of some arbitrary bytes.") - def decodeHex: Bytes = try new Bytes(Hex.decodeHex(wrapped.toCharArray)) catch { + def decodeHex: Bytes = try new Bytes(Hex.decodeHex(wrapped.toCharArray)) + catch { case e: DecoderException => throw new IllegalArgumentException(e) } @@ -109,12 +127,15 @@ final class StringMiscOps(private val wrapped: String) extends AnyVal { throw new IllegalArgumentException(e) } - @Documentation("Calculates MD5 digest from contents of this string encoded using UTF-8. " + - "The output is a 32 character hexadecimal string.") + @Documentation( + "Calculates MD5 digest from contents of this string encoded using UTF-8. " + + "The output is a 32 character hexadecimal string." + ) def md5Hex: String = DigestUtils.md5Hex(wrapped.getBytes(StandardCharsets.UTF_8)) - @Documentation("Calculates HMAC MD5 digest from contents of this string. " + - "The output is a 32 character hexadecimal string.") + @Documentation( + "Calculates HMAC MD5 digest from contents of this string. " + "The output is a 32 character hexadecimal string." + ) def hmacMD5(key: String): String = new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(wrapped) @Documentation("Returns this string in lowercase.") diff --git a/scex-util/src/main/scala/com/avsystem/scex/util/StringNetworkOps.scala b/scex-util/src/main/scala/com/avsystem/scex/util/StringNetworkOps.scala index 90cc0a53..b02d3516 100644 --- a/scex-util/src/main/scala/com/avsystem/scex/util/StringNetworkOps.scala +++ b/scex-util/src/main/scala/com/avsystem/scex/util/StringNetworkOps.scala @@ -7,13 +7,17 @@ import com.avsystem.scex.presentation.annotation.Documentation final class StringNetworkOps(private val wrapped: String) extends AnyVal { - @Documentation("Returns true if the string is an IPv4 address which belongs to the subnet provided as the " + - "`subnetWithMask` argument. Use CIDR notation for the argument, e.g. `10.8.0.0/16`.") + @Documentation( + "Returns true if the string is an IPv4 address which belongs to the subnet provided as the " + + "`subnetWithMask` argument. Use CIDR notation for the argument, e.g. `10.8.0.0/16`." + ) def isIpInSubnet(subnetWithMask: String): Boolean = NetFunctions.isIpInSubnet(wrapped, subnetWithMask) - @Documentation("Returns true if the string is an IPv4 address which belongs to the subnet defined by the `subnet` and 'mask' arguments." + - "Use dot-decimal notation for the arguments.") + @Documentation( + "Returns true if the string is an IPv4 address which belongs to the subnet defined by the `subnet` and 'mask' arguments." + + "Use dot-decimal notation for the arguments." + ) def isIpInSubnetWithMask(subnet: String, mask: String): Boolean = NetFunctions.isIpInSubnetWithMask(wrapped, subnet, mask) @@ -26,7 +30,9 @@ final class StringNetworkOps(private val wrapped: String) extends AnyVal { @Documentation("Returns true if the string is a valid hardware address.") def isMac: Boolean = NetFunctions.isMac(wrapped) - @Documentation("Returns 0 if this address is equal to the one provided as the argument, -1 if less than, 1 if greater than.") + @Documentation( + "Returns 0 if this address is equal to the one provided as the argument, -1 if less than, 1 if greater than." + ) def compareAsIpTo(ip: String): Integer = try { val adr1 = InetAddress.getByName(wrapped) val adr2 = InetAddress.getByName(ip)