/
Java.scala
99 lines (85 loc) · 4.81 KB
/
Java.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.twilio.guardrail.generators.syntax
import cats.implicits._
import com.github.javaparser.JavaParser
import com.github.javaparser.ast.{CompilationUnit, ImportDeclaration}
import com.github.javaparser.ast.`type`.{ClassOrInterfaceType, Type}
import com.github.javaparser.ast.body.Parameter
import com.github.javaparser.ast.expr.{Expression, Name, SimpleName}
import com.github.javaparser.printer.PrettyPrinterConfiguration
import com.github.javaparser.printer.PrettyPrinterConfiguration.IndentType
import com.twilio.guardrail.Target
import java.util.Optional
import scala.reflect.ClassTag
import scala.util.Try
object Java {
implicit class RichJavaOptional[T](val o: Optional[T]) extends AnyVal {
def asScala: Option[T] = if (o.isPresent) Option(o.get) else None
}
implicit class RichType(val tpe: Type) extends AnyVal {
def isOptional: Boolean =
tpe match {
case cls: ClassOrInterfaceType =>
val scope = cls.getScope.asScala
cls.getNameAsString == "Optional" && (scope.isEmpty || scope.map(_.asString).contains("java.util"))
case _ => false
}
def containedType: Type =
tpe match {
case cls: ClassOrInterfaceType => cls.getTypeArguments.asScala.filter(_.size == 1).fold(tpe)(_.get(0))
case _ => tpe
}
def isNamed(name: String): Boolean =
tpe match {
case cls: ClassOrInterfaceType if name.contains(".") => (cls.getScope.asScala.fold("")(_ + ".") + cls.getNameAsString) == name
case cls: ClassOrInterfaceType => cls.getNameAsString == name
case _ => false
}
def name: Option[String] =
tpe match {
case cls: ClassOrInterfaceType => Some(cls.getScope.asScala.fold("")(_ + ".") + cls.getNameAsString)
case _ => None
}
}
private[this] def safeParse[T](log: String)(parser: String => T, s: String)(implicit cls: ClassTag[T]): Target[T] = {
Target.log.debug(log)(s) >> (
Try(parser(s)).toEither.fold(t => Target.raiseError(s"Unable to parse '${s}' to a ${cls.runtimeClass.getName}: ${t.getMessage}"), Target.pure)
)
}
def safeParseCode(s: String): Target[CompilationUnit] = safeParse("safeParseCode")(JavaParser.parse, s)
def safeParseSimpleName(s: String): Target[SimpleName] = safeParse("safeParseSimpleName")(JavaParser.parseSimpleName, s)
def safeParseName(s: String): Target[Name] = safeParse("safeParseName")(JavaParser.parseName, s)
def safeParseType(s: String): Target[Type] = safeParse("safeParseType")(JavaParser.parseType, s)
def safeParseClassOrInterfaceType(s: String): Target[ClassOrInterfaceType] = safeParse("safeParseClassOrInterfaceType")(JavaParser.parseClassOrInterfaceType, s)
def safeParseExpression[T <: Expression](s: String)(implicit cls: ClassTag[T]): Target[T] = safeParse[T]("safeParseExpression")(JavaParser.parseExpression[T], s)
def safeParseParameter(s: String): Target[Parameter] = safeParse("safeParseParameter")(JavaParser.parseParameter, s)
def safeParseImport(s: String): Target[ImportDeclaration] = safeParse("safeParseImport")(JavaParser.parseImport, s)
def safeParseRawImport(s: String): Target[ImportDeclaration] = safeParse("safeParseRawImport")(JavaParser.parseImport, s"import ${s};")
def safeParseRawStaticImport(s: String): Target[ImportDeclaration] = safeParse("safeParseStaticImport")(JavaParser.parseImport, s"import static ${s};")
def completionStageType: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("CompletionStage" )
def optionalType: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("Optional")
def functionType: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("Function")
val STRING_TYPE: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("String")
val THROWABLE_TYPE: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("Throwable")
val ASSERTION_ERROR_TYPE: ClassOrInterfaceType = JavaParser.parseClassOrInterfaceType("AssertionError")
val printer: PrettyPrinterConfiguration = new PrettyPrinterConfiguration()
.setColumnAlignFirstMethodChain(true)
.setColumnAlignParameters(true)
.setIndentSize(4)
.setIndentType(IndentType.SPACES)
.setOrderImports(true)
.setPrintComments(true)
.setPrintJavadoc(true)
.setTabWidth(4)
/*
implicit class PrintStructure(value: Node) {
def toAST: String = {
@scala.annotation.tailrec
def walk(chunks: List[(String, Int, List[Node], String)]) = {
chunks.flatMap { case (pre, level, nodes, post) =>
}
}
walk(List(("", 0, List(value), "")))
}
}
*/
}