scala.tools.nsc.Global Scala Examples
The following examples show how to use scala.tools.nsc.Global.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: AnalyzerPlugin.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.plugins.{Plugin, PluginComponent} import scala.tools.nsc.{Global, Phase} final class AnalyzerPlugin(val global: Global) extends Plugin { plugin => override def init(options: List[String], error: String => Unit): Boolean = { options.foreach { option => val level = option.charAt(0) match { case '-' => Level.Off case '*' => Level.Info case '+' => Level.Error case _ => Level.Warn } val nameArg = if (level != Level.Warn) option.drop(1) else option if (nameArg == "_") { rules.foreach(_.level = level) } else { val (name, arg) = nameArg.split(":", 2) match { case Array(n, a) => (n, a) case Array(n) => (n, null) } rulesByName.get(name) match { case Some(rule) => rule.level = level rule.argument = arg case None => error(s"Unrecognized AVS analyzer rule: $name") } } } true } private lazy val rules = List( new ImportJavaUtil(global), new VarargsAtLeast(global), new CheckMacroPrivate(global), new ExplicitGenerics(global), new ValueEnumExhaustiveMatch(global), new ShowAst(global), new FindUsages(global), new CheckBincompat(global), new Any2StringAdd(global), new ThrowableObjects(global) ) private lazy val rulesByName = rules.map(r => (r.name, r)).toMap val name = "AVSystemAnalyzer" val description = "AVSystem custom Scala static analyzer" val components: List[PluginComponent] = List(component) private object component extends PluginComponent { val global: plugin.global.type = plugin.global val runsAfter = List("typer") override val runsBefore = List("patmat", "silencer") val phaseName = "avsAnalyze" import global._ def newPhase(prev: Phase) = new StdPhase(prev) { def apply(unit: CompilationUnit): Unit = rules.foreach(rule => if (rule.level != Level.Off) rule.analyze(unit.asInstanceOf[rule.global.CompilationUnit])) } } }
Example 2
Source File: CompanionUtils.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.utils import scala.reflect.macros.{blackbox, runtime} import scala.tools.nsc.Global trait CompanionUtils { val c: blackbox.Context // Copied from Magnolia: https://github.com/propensive/magnolia/blob/master/core/shared/src/main/scala/globalutil.scala // From Shapeless: https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/generic.scala#L698 // Cut-n-pasted (with most original comments) and slightly adapted from // https://github.com/scalamacros/paradise/blob/c14c634923313dd03f4f483be3d7782a9b56de0e/plugin/src/main/scala/org/scalamacros/paradise/typechecker/Namers.scala#L568-L613 def patchedCompanionRef(c: blackbox.Context)(tpe: c.Type): c.Tree = { // see https://github.com/scalamacros/paradise/issues/7 // also see https://github.com/scalamacros/paradise/issues/64 val global = c.universe.asInstanceOf[Global] val typer = c.asInstanceOf[runtime.Context].callsiteTyper.asInstanceOf[global.analyzer.Typer] val ctx = typer.context val globalType = tpe.asInstanceOf[global.Type] val original = globalType.typeSymbol val owner = original.owner val companion = original.companion.orElse { import global.{abort => aabort, _} implicit class PatchedContext(ctx: global.analyzer.Context) { trait PatchedLookupResult { def suchThat(criterion: Symbol => Boolean): Symbol } def patchedLookup(name: Name, expectedOwner: Symbol) = new PatchedLookupResult { override def suchThat(criterion: Symbol => Boolean): Symbol = { var res: Symbol = NoSymbol var ctx = PatchedContext.this.ctx while (res == NoSymbol && ctx.outer != ctx) { // NOTE: original implementation says `val s = ctx.scope lookup name` // but we can't use it, because Scope.lookup returns wrong results when the lookup is ambiguous // and that triggers https://github.com/scalamacros/paradise/issues/64 val s = { val lookupResult = ctx.scope.lookupAll(name).filter(criterion).toList lookupResult match { case Nil => NoSymbol case List(unique) => unique case _ => aabort(s"unexpected multiple results for a companion symbol lookup for $original#{$original.id}") } } if (s != NoSymbol && s.owner == expectedOwner) res = s else ctx = ctx.outer } res } } } ctx.patchedLookup(original.name.companionName, owner) suchThat { sym => (original.isTerm || sym.hasModuleFlag) && (sym isCoDefinedWith original) } } global.gen.mkAttributedRef(globalType.prefix, companion).asInstanceOf[c.Tree] } }
Example 3
Source File: InjectReporter.scala From scala-clippy with Apache License 2.0 | 5 votes |
package com.softwaremill.clippy import scala.reflect.internal.util.Position import scala.tools.nsc.plugins.PluginComponent import scala.tools.nsc.{Global, Phase} abstract class InjectReporter( handleError: (Position, String) => String, getFatalWarningAdvice: String => Option[Warning], superGlobal: Global ) extends PluginComponent { override val global = superGlobal def colorsConfig: ColorsConfig def isEnabled: Boolean override val runsAfter = List[String]("parser") override val runsBefore = List[String]("namer") override val phaseName = "inject-clippy-reporter" override def newPhase(prev: Phase) = new Phase(prev) { override def name = phaseName override def description = "Switches the reporter to Clippy's reporter chain" override def run(): Unit = if (isEnabled) { val r = global.reporter global.reporter = new FailOnWarningsReporter( new DelegatingReporter(r, handleError, colorsConfig), getFatalWarningAdvice, colorsConfig ) } } }
Example 4
Source File: Definitions.scala From scalaz-plugin with GNU Lesser General Public License v3.0 | 5 votes |
package scalaz.plugin import scala.tools.nsc.Global abstract class Definitions { val global: Global import global._, analyzer._ def init(): Unit = { ScalazPackage ScalazMetaPackage MinimalAttr } lazy val ScalazPackage = ensurePackage(rootMirror.RootClass, "scalaz") lazy val ScalazMetaPackage = ensurePackage(ScalazPackage.moduleClass, "meta") lazy val UnmixinAttr: ClassSymbol = rootMirror.getRequiredClass("scalaz.meta.unmixin") lazy val InstancesAttr: ClassSymbol = rootMirror.getRequiredClass("scalaz.meta.instances") lazy val TypeclassClass: ClassSymbol = rootMirror.getRequiredClass("scalaz.meta.Typeclass") lazy val TypeclassType: Type = TypeclassClass.tpe lazy val OrphanAttr: ClassSymbol = rootMirror.getRequiredClass("scalaz.meta.orphan") lazy val EnableOrphansFlag: ClassSymbol = rootMirror.getRequiredClass("scalaz.meta.features.orphans") lazy val MinimalAttr = rootMirror.getClassIfDefined(TypeName("scalaz.meta.minimal")).orElse { val scope = newScope val ann = ScalazMetaPackage.moduleClass .newClassWithInfo( TypeName("minimal"), definitions.StaticAnnotationClass.typeOfThis :: Nil, scope, newFlags = Flag.SYNTHETIC ) val ctor = ann.newConstructor(NoPosition) val param = ctor .newValueParameter(TermName("defns")) .setInfo(typeRef(NoPrefix, definitions.RepeatedParamClass, definitions.AnyTpe :: Nil)) ann.info.decls.enter { ctor.setInfo(MethodType(param :: Nil, ann.typeOfThis)) } ScalazMetaPackage.moduleClass.info.decls.enter(ann) } private def ensurePackage(owner: Symbol, name: String): Symbol = { val emptyTempl = ( Template(Nil, noSelfType, Nil) setSymbol NoSymbol setType NoType ) rootMirror.getPackageIfDefined(TermName(owner.name + name)).orElse { newNamer(NoContext.make(emptyTempl, owner, owner.info.decls)) .createPackageSymbol(NoPosition, Ident(TermName(name))) } } }
Example 5
Source File: SCTags.scala From sctags with Apache License 2.0 | 5 votes |
package sctags import scala.tools.nsc.{Settings, Global} import scala.tools.nsc.reporters.StoreReporter import scala.collection.mutable.ListBuffer import java.io.File import java.io.PrintStream object SCTags extends Parsing with TagGeneration { import FileUtils._; var outputFile: String = "tags"; var recurse = false; var etags = false def parseOpt(args:List[String]): List[String] = args match { case ("-f" |"-o") :: file :: rest => outputFile = file; parseOpt(rest) case ("-R" |"--recurse" ) :: rest => recurse = true; parseOpt(rest) case ("-e" |"--etags" ) :: rest => etags = true; parseOpt(rest) case files => files } def error(str: String) = System.err.println("Error: " + str); val settings = new Settings(error); val reporter = new StoreReporter; val compiler = new Global(settings, reporter); def run(fnames: Seq[String]) { val files = new ListBuffer[File] fnames foreach { fname => val file = new File(fname) if (file.isDirectory) { if (recurse) files ++= listFilesRecursive(file, {(f: File) => f.getName.endsWith(".scala")}) else System.err.println("Skipping directory " + fname); } else { if (file.getName.endsWith(".scala")) files += file else System.err.println("Skipping file " + fname); } } if (files.nonEmpty) { val tags = files.map(f => (f.getPath, generateTags(parse(f)))) val output = outputFile match { case "-" => Console.out case "tags" if etags => new PrintStream("TAGS") case x => new PrintStream(x) } if (etags) { ETags.generate(tags, output) } else { CTags.generate(tags, output) } } } def main(args: Array[String]): Unit = { val fnames = parseOpt(args.toList) run(fnames) } }
Example 6
Source File: Parsing.scala From sctags with Apache License 2.0 | 5 votes |
package sctags import scala.tools.nsc.{Global, CompilationUnits} import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.ast.Trees import scala.tools.nsc.ast.parser.SyntaxAnalyzer import scala.reflect.internal.util.BatchSourceFile import java.io.File; trait Parsing { this: SCTags.type => import compiler.syntaxAnalyzer._ import compiler._ def parse(af: AbstractFile): Tree = parse(new CompilationUnit(new BatchSourceFile(af))) def parse(f: File): Tree = parse(AbstractFile.getFile(f)) def parse(fname: String): Tree = parse(AbstractFile.getFile(fname)) def parse(cu: CompilationUnit): Tree = { new compiler.Run val parser = new UnitParser(cu) val tree = parser.compilationUnit compiler.analyzer.newNamer(compiler.analyzer.rootContext(cu, tree, false)).enterSym(tree) tree } }
Example 7
Source File: AnnotationDataBuilder.scala From ScalaClean with Apache License 2.0 | 5 votes |
package org.scalaclean.analysis.plugin import org.scalaclean.analysis.{AnnotationData, ExtensionData} import scala.tools.nsc.Global object AnnotationDataBuilder { def buildSimpleAnnotation(g: Global)(annotated: g.Tree, annotation: g.AnnotationInfo): ExtensionData = { def print(assoc: g.ClassfileAnnotArg): String = { import g._ assoc match { case LiteralAnnotArg(const) => const.value.toString case ArrayAnnotArg(args) => args.map(print).mkString(";") case NestedAnnotArg(annInfo) => val clazz = annInfo.tpe.typeSymbol.fullName //TODO if we really need it clean(s"@$clazz(<TODO>)") case UnmappableAnnotArg => ??? case ScalaSigBytes(_) => ??? } } val clazz = annotation.tpe.typeSymbol.fullName val targetPos = annotated.pos val pos = annotation.pos var values = Map.empty[String, String] annotation.assocs foreach { case (name, assoc) => values = values.updated(name.toString, clean(print(assoc))) } //TODO cope better with trees - this should cope with @foo(1,2,"hello") //TODO cope better with trees - need @foo(x = 1, y = 2, z = "hello") for (i <- annotation.scalaArgs.indices) { values = values.updated(i.toString, clean(annotation.constantAtIndex(i).map(_.value.toString).getOrElse("<<<TODO>>>"))) } val start = if (pos.isDefined) pos.start - targetPos.start else Int.MinValue val end = if (pos.isDefined) pos.end - targetPos.start else Int.MinValue AnnotationData(start, end, clazz, values) } private def clean(s: String): String = s. // replace(',', ';'). replace("\n", "\\n"). replace("\r", "\\r") }
Example 8
Source File: ScalaCleanCompilerPlugin.scala From ScalaClean with Apache License 2.0 | 5 votes |
package org.scalaclean.analysis import org.scalaclean.analysis.plugin.{ExtensionPlugin, ExtensionPluginFactory, JunitPlugin, ModsPlugin} import scala.tools.nsc.Global import scala.tools.nsc.plugins.{Plugin, PluginComponent} class ScalaCleanCompilerPlugin(override val global: Global) extends Plugin { override val name: String = "scalaclean-analysis-plugin" override val description: String = "ScalaClean analysis plugin" val component = new ScalaCompilerPluginComponent(global) //hardcoded for the moment component.extensions += ModsPlugin.create(component, "") component.extensions += JunitPlugin.create(component, "") override def processOptions( options: List[String], error: String => Unit): Unit = { import scala.reflect.runtime.universe val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader) val realOptions = options.distinct component.options = realOptions for (option <- realOptions) { if (option == "debug:true") { component.debug = true } else if (option.startsWith("extension:")) { val end = { val end = option.indexOf(':', 10) if (end == -1) option.length else end } val fqn = option.substring(10, end) val module = runtimeMirror.staticModule(fqn) runtimeMirror.reflectModule(module).instance match { case valid: ExtensionPluginFactory => component.extensions += valid.create(component, option.substring(end)) case null => throw new IllegalArgumentException("not a valid Extension FQN - expected the name of an object") case invalid => throw new IllegalArgumentException(s"not a valid Extension FQN - ${invalid.getClass.getName} is not a ${classOf[ExtensionDescriptor[_]].getName}") } } else if (option.startsWith("srcdirs:")) { component.sourceDirs = option.substring(8).split(java.io.File.pathSeparatorChar).toList } else error(s"Option not recognised: $option") } } override val optionsHelp: Option[String] = Some( // s"""-P:$name:debug:true Set debugging on the ScalaClean analysis plugin |-P:$name:srcdirs The path of sources, separated by ${java.io.File.pathSeparatorChar} |-P:$name:extension:<fqn> Add an extension dataset. FQN is the fully qualified name of the appropriate ExtensionDescriptor object |""".stripMargin) override val components: List[PluginComponent] = List(component) }
Example 9
Source File: AnalyzerTest.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import org.scalactic.source.Position import org.scalatest.Assertions import scala.reflect.internal.util.BatchSourceFile import scala.tools.nsc.plugins.Plugin import scala.tools.nsc.{Global, Settings} trait AnalyzerTest { this: Assertions => val settings = new Settings settings.usejavacp.value = true settings.pluginOptions.value ++= List("AVSystemAnalyzer:+_") val compiler: Global = new Global(settings) { global => override protected def loadRoughPluginsList(): List[Plugin] = new AnalyzerPlugin(global) :: super.loadRoughPluginsList() } def compile(source: String): Unit = { compiler.reporter.reset() val run = new compiler.Run run.compileSources(List(new BatchSourceFile("test.scala", source))) } def assertErrors(source: String)(implicit pos: Position): Unit = { compile(source) assert(compiler.reporter.hasErrors) } def assertErrors(errors: Int, source: String)(implicit pos: Position): Unit = { compile(source) assert(compiler.reporter.errorCount == errors) } def assertNoErrors(source: String)(implicit pos: Position): Unit = { compile(source) assert(!compiler.reporter.hasErrors) } }
Example 10
Source File: ExplicitGenerics.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class ExplicitGenerics(g: Global) extends AnalyzerRule(g, "explicitGenerics") { import global._ lazy val explicitGenericsAnnotTpe = classType("com.avsystem.commons.annotation.explicitGenerics") def analyze(unit: CompilationUnit) = if (explicitGenericsAnnotTpe != NoType) { def requiresExplicitGenerics(sym: Symbol): Boolean = sym != NoSymbol && (sym :: sym.overrides).flatMap(_.annotations).exists(_.tree.tpe <:< explicitGenericsAnnotTpe) def analyzeTree(tree: Tree): Unit = analyzer.macroExpandee(tree) match { case `tree` | EmptyTree => tree match { case t@TypeApply(pre, args) if requiresExplicitGenerics(pre.symbol) => val inferredTypeParams = args.forall { case tt: TypeTree => tt.original == null || tt.original == EmptyTree case _ => false } if (inferredTypeParams) { report(t.pos, s"${pre.symbol} requires that its type arguments are explicit (not inferred)") } case _ => } tree.children.foreach(analyzeTree) case prevTree => analyzeTree(prevTree) } analyzeTree(unit.body) } }
Example 11
Source File: CheckMacroPrivate.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class CheckMacroPrivate(g: Global) extends AnalyzerRule(g, "macroPrivate") { import global._ lazy val macroPrivateAnnotTpe = classType("com.avsystem.commons.annotation.macroPrivate") def analyze(unit: CompilationUnit) = if (macroPrivateAnnotTpe != NoType) { def analyzeTree(tree: Tree): Unit = analyzer.macroExpandee(tree) match { case `tree` | EmptyTree => tree match { case _: Ident | _: Select | _: SelectFromTypeTree | _: New if tree.symbol != null && tree.pos != NoPosition => val sym = tree.symbol val macroPrivate = (sym :: sym.overrides).iterator .flatMap(_.annotations).exists(_.tree.tpe <:< macroPrivateAnnotTpe) if (macroPrivate) { report(tree.pos, s"$sym can only be used in macro-generated code") } case _ => } tree.children.foreach(analyzeTree) case prevTree => analyzeTree(prevTree) } analyzeTree(unit.body) } }
Example 12
Source File: ValueEnumExhaustiveMatch.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.collection.mutable import scala.tools.nsc.Global class ValueEnumExhaustiveMatch(g: Global) extends AnalyzerRule(g, "valueEnumExhaustiveMatch") { import global._ lazy val valueEnumTpe: Type = classType("com.avsystem.commons.misc.ValueEnum") lazy val ExistentialType(_, TypeRef(miscPackageTpe, valueEnumCompanionSym, _)) = classType("com.avsystem.commons.misc.ValueEnumCompanion") def analyze(unit: CompilationUnit): Unit = if (valueEnumTpe != NoType) { unit.body.foreach(analyzeTree { case tree@Match(selector, cases) if selector.tpe <:< valueEnumTpe => val expectedCompanionTpe = TypeRef(miscPackageTpe, valueEnumCompanionSym, List(selector.tpe)) val companion = selector.tpe.typeSymbol.companion val companionTpe = companion.toType if (companionTpe <:< expectedCompanionTpe) { val unmatched = new mutable.LinkedHashSet[Symbol] companionTpe.decls.iterator .filter(s => s.isVal && s.isFinal && !s.isLazy && s.typeSignature <:< selector.tpe) .map(_.getterIn(companion)).filter(_.isPublic).foreach(unmatched.add) def findMatchedEnums(pattern: Tree): Unit = pattern match { case Bind(_, body) => findMatchedEnums(body) case Alternative(patterns) => patterns.foreach(findMatchedEnums) case Ident(termNames.WILDCARD) => unmatched.clear() case _: Ident | _: Select => unmatched.remove(pattern.symbol) case _: Literal => case _ => unmatched.clear() } cases.iterator.foreach { case CaseDef(pattern, EmptyTree, _) => findMatchedEnums(pattern) case _ => unmatched.clear() } if (unmatched.nonEmpty) { val what = if (unmatched.size > 1) "inputs: " + unmatched.map(_.nameString).mkString(", ") else "input: " + unmatched.head.nameString report(tree.pos, "match may not be exhaustive.\nIt would fail on the following " + what) } } }) } }
Example 13
Source File: ThrowableObjects.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class ThrowableObjects(g: Global) extends AnalyzerRule(g, "throwableObjects", Level.Warn) { import global._ private lazy val throwableTpe = typeOf[Throwable] private lazy val throwableSym = throwableTpe.dealias.typeSymbol def analyze(unit: CompilationUnit): Unit = unit.body.foreach { case md: ModuleDef => val tpe = md.symbol.typeSignature def fillInStackTraceSym: Symbol = tpe.member(TermName("fillInStackTrace")).alternatives.find(_.paramLists == List(Nil)).get if (tpe <:< throwableTpe && fillInStackTraceSym.owner == throwableSym) { report(md.pos, "objects should never extend Throwable unless they have no stack trace") } case _ => } }
Example 14
Source File: ShowAst.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class ShowAst(g: Global) extends AnalyzerRule(g, "showAst", Level.Error) { import global._ lazy val showAstAnnotType: Type = classType("com.avsystem.commons.annotation.showAst") def analyze(unit: CompilationUnit) = if (showAstAnnotType != NoType) { def analyzeTree(tree: Tree): Unit = analyzer.macroExpandee(tree) match { case `tree` | EmptyTree => tree match { case Annotated(annot, arg) if annot.tpe <:< showAstAnnotType => report(arg.pos, showCode(arg)) case Typed(expr, tpt) if tpt.tpe.annotations.exists(_.tpe <:< showAstAnnotType) => report(expr.pos, showCode(expr)) case _: MemberDef if tree.symbol.annotations.exists(_.tpe <:< showAstAnnotType) => report(tree.pos, showCode(tree)) case _ => } tree.children.foreach(analyzeTree) case prevTree => analyzeTree(prevTree) } analyzeTree(unit.body) } }
Example 15
Source File: ScaladocExtractor.scala From naptime with Apache License 2.0 | 5 votes |
package org.coursera.naptime.sbt import sbt.File import scala.reflect.internal.util.Position import scala.tools.nsc.Global import scala.tools.nsc.doc.DocFactory import scala.tools.nsc.doc.Settings import scala.tools.nsc.doc.base.CommentFactoryBase import scala.tools.nsc.doc.base.LinkTo import scala.tools.nsc.doc.base.LinkToExternal import scala.tools.nsc.doc.base.LinkToMember import scala.tools.nsc.doc.base.MemberLookupBase import scala.tools.nsc.doc.base.comment.Comment import scala.tools.nsc.doc.model.MemberEntity import scala.tools.nsc.reporters.AbstractReporter object ScaladocExtractor { class ScaladocCommentFactory(compiler: Global, settings: Settings) extends CommentFactoryBase with MemberLookupBase { override val global: compiler.type = compiler override def internalLink(sym: global.Symbol, site: global.Symbol): Option[LinkTo] = None override def findExternalLink(sym: global.Symbol, name: String): Option[LinkToExternal] = None override def warnNoLink: Boolean = false override def toString(link: LinkTo): String = link.toString override def chooseLink(links: List[LinkTo]): LinkTo = { val members = links.collect { case linkToMember@LinkToMember(member: MemberEntity, _) => (member, linkToMember) } if (members.isEmpty) { links.head } else { members.min(Ordering[MemberEntity].on[(MemberEntity, LinkTo)](_._1))._2 } } private[this] def parseComment(symbol: compiler.Symbol, docComment: compiler.DocComment): Comment = { parseAtSymbol(docComment.raw, "", docComment.pos, Some(symbol)) } def getComments: Map[String, Comment] = { compiler.docComments.map { case (symbol, docComment) => symbol.fullName -> parseComment(symbol, docComment) }.toMap } } def analyze(sourceFiles: Seq[File]): Map[String, Comment] = { val settings = new Settings(error => (), message => ()) val scalaLibraryPath = ScalaLibraryLocator.getPath.getOrElse { throw new Exception("Could not get path to SBT's Scala library for Scaladoc generation") } settings.bootclasspath.append(scalaLibraryPath) settings.classpath.append(scalaLibraryPath) val reporter = new BlackHoleReporter(settings) val docFactory = new DocFactory(reporter, settings) val compiler = docFactory.compiler docFactory.makeUniverse(Left(sourceFiles.toList.map(_.getAbsolutePath))) val commentFactory = new ScaladocCommentFactory(compiler, settings) commentFactory.getComments } } class BlackHoleReporter(override val settings: Settings) extends AbstractReporter { override def display(pos: Position, msg: String, severity: Severity): Unit = () override def displayPrompt(): Unit = () }
Example 16
Source File: AnalyzerRule.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import java.io.{PrintWriter, StringWriter} import scala.tools.nsc.Global import scala.util.control.NonFatal abstract class AnalyzerRule(val global: Global, val name: String, defaultLevel: Level = Level.Warn) { import global._ var level: Level = defaultLevel var argument: String = _ protected def classType(fullName: String): Type = try rootMirror.staticClass(fullName).asType.toType.erasure catch { case _: ScalaReflectionException => NoType } protected def analyzeTree(fun: PartialFunction[Tree, Unit])(tree: Tree): Unit = try fun.applyOrElse(tree, (_: Tree) => ()) catch { case NonFatal(t) => val sw = new StringWriter t.printStackTrace(new PrintWriter(sw)) reporter.error(tree.pos, s"Analyzer rule $this failed: " + sw.toString) } private def adjustMsg(msg: String): String = s"[AVS] $msg" protected def report(pos: Position, message: String): Unit = level match { case Level.Off => case Level.Info => reporter.echo(pos, adjustMsg(message)) case Level.Warn => reporter.warning(pos, adjustMsg(message)) case Level.Error => reporter.error(pos, adjustMsg(message)) } def analyze(unit: CompilationUnit): Unit override def toString: String = getClass.getSimpleName } sealed trait Level object Level { case object Off extends Level case object Info extends Level case object Warn extends Level case object Error extends Level }
Example 17
Source File: VarargsAtLeast.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class VarargsAtLeast(g: Global) extends AnalyzerRule(g, "varargsAtLeast") { import global._ lazy val atLeastAnnotTpe = classType("com.avsystem.commons.annotation.atLeast") def analyze(unit: CompilationUnit): Unit = if (atLeastAnnotTpe != NoType) { def isVarargParam(tree: Tree) = tree match { case Typed(_, Ident(typeNames.WILDCARD_STAR)) => true case _ => false } unit.body.foreach(analyzeTree { case t@Apply(fun, args) if fun.tpe.params.lastOption.map(_.tpe.typeSymbol).contains(definitions.RepeatedParamClass) && !args.lastOption.exists(isVarargParam) => val required = fun.tpe.params.last.annotations.find(_.tree.tpe <:< atLeastAnnotTpe).map(_.tree.children.tail).collect { case List(Literal(Constant(n: Int))) => n }.getOrElse(0) val actual = args.size - fun.tpe.params.size + 1 if (actual < required) { report(t.pos, s"This method requires at least $required arguments for its repeated parameter, $actual passed.") } }) } }
Example 18
Source File: CheckBincompat.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class CheckBincompat(g: Global) extends AnalyzerRule(g, "bincompat") { import global._ private lazy val bincompatAnnotType = classType("com.avsystem.commons.annotation.bincompat") def analyze(unit: CompilationUnit): Unit = unit.body.foreach(analyzeTree { case tree@(_: Ident | _: Select | _: New) if tree.symbol != null && tree.symbol.annotations.exists(_.tree.tpe <:< bincompatAnnotType) => report(tree.pos, "Symbols annotated as @bincompat exist only for binary compatibility " + "and should not be used directly") }) }
Example 19
Source File: Any2StringAdd.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class Any2StringAdd(g: Global) extends AnalyzerRule(g, "any2stringadd", Level.Off) { import global._ private lazy val any2stringaddSym = typeOf[Predef.type].member(TermName("any2stringadd")).alternatives.find(_.isMethod).get def analyze(unit: CompilationUnit): Unit = { unit.body.foreach(analyzeTree { case t if t.symbol == any2stringaddSym => report(t.pos, "concatenating arbitrary values with strings is disabled, " + "use explicit toString or string interpolation") }) } }
Example 20
Source File: ImportJavaUtil.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class ImportJavaUtil(g: Global) extends AnalyzerRule(g, "importJavaUtil") { import global._ def analyze(unit: CompilationUnit): Unit = { unit.body.foreach(analyzeTree { case tree@q"import java.util" => report(tree.pos, "Don't import java.util: either import with rename (e.g. import java.{util => ju}) " + "or use type aliases from JavaInterop (e.g. JList, JSet, etc)") }) } }
Example 21
Source File: FindUsages.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import scala.tools.nsc.Global class FindUsages(g: Global) extends AnalyzerRule(g, "findUsages") { import global._ lazy val rejectedSymbols: Set[String] = if (argument == null) Set.empty else argument.split(";").toSet override def analyze(unit: CompilationUnit): Unit = if (rejectedSymbols.nonEmpty) { unit.body.foreach { tree => if (tree.symbol != null && rejectedSymbols.contains(tree.symbol.fullName)) { report(tree.pos, s"found usage of ${tree.symbol.fullName}") } } } }
Example 22
Source File: Runtimes.scala From AppCrawler with Apache License 2.0 | 5 votes |
package com.testerhome.appcrawler import java.io.File import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader import scala.tools.nsc.interpreter.IMain import scala.tools.nsc.{Global, Settings} class Runtimes(val outputDir:String="") extends CommonLog{ private val settingsCompile=new Settings() if(outputDir.nonEmpty){ val tempDir=new File(outputDir) if(tempDir.exists()==false){ tempDir.mkdir() } settingsCompile.outputDirs.setSingleOutput(this.outputDir) } settingsCompile.deprecation.value = true // enable detailed deprecation warnings settingsCompile.unchecked.value = true // enable detailed unchecked warnings settingsCompile.usejavacp.value = true val global = new Global(settingsCompile) val run = new global.Run private val settingsEval=new Settings() settingsEval.deprecation.value = true // enable detailed deprecation warnings settingsEval.unchecked.value = true // enable detailed unchecked warnings settingsEval.usejavacp.value = true val interpreter = new IMain(settingsEval) def compile(fileNames:List[String]): Unit ={ run.compile(fileNames) } def eval(code:String): Unit ={ interpreter.interpret(code) } def reset(): Unit ={ } } object Runtimes extends CommonLog{ var instance=new Runtimes() var isLoaded=false def apply(): Unit ={ } def eval(code:String): Unit ={ if(isLoaded==false){ log.info("first import") instance.eval("val driver=com.testerhome.appcrawler.AppCrawler.crawler.driver") instance.eval("def crawl(depth:Int)=com.testerhome.appcrawler.AppCrawler.crawler.crawl(depth)") isLoaded=true } log.info(code) instance.eval(code) log.info("eval finish") } def compile(fileNames:List[String]): Unit ={ instance.compile(fileNames) isLoaded=false } def init(classDir:String=""): Unit ={ instance=new Runtimes(classDir) } def reset(): Unit ={ } def loadPlugins(pluginDir:String=""): List[Plugin] ={ val pluginDirFile=new java.io.File(pluginDir) if(pluginDirFile.exists()==false){ log.warn(s"no ${pluginDir} directory, skip") return Nil } val pluginFiles=pluginDirFile.list().filter(_.endsWith(".scala")).toList val pluginClassNames=pluginFiles.map(_.split(".scala").head) log.info(s"find plugins in ${pluginDir}") log.info(pluginFiles) log.info(pluginClassNames) val runtimes=new Runtimes(pluginDir) runtimes.compile(pluginFiles.map(pluginDirFile.getCanonicalPath+File.separator+_)) val urls=Seq(pluginDirFile.toURI.toURL, getClass.getProtectionDomain.getCodeSource.getLocation) val loader=new URLClassLoader(urls, Thread.currentThread().getContextClassLoader) pluginClassNames.map(loader.loadClass(_).newInstance().asInstanceOf[Plugin]) } }
Example 23
Source File: TypedHolesPlugin.scala From scala-typed-holes with Apache License 2.0 | 5 votes |
package holes import scala.collection.mutable import scala.tools.nsc.{Global, Phase} import scala.tools.nsc.transform.Transform import scala.tools.nsc.ast.TreeDSL import scala.tools.nsc.plugins.{Plugin, PluginComponent} class TypedHolesPlugin(val global: Global) extends Plugin { val name = "typed-holes" val description = "Treat use of ??? as a hole and give a useful warning about it" private var logLevel: LogLevel = LogLevel.Warn override def init(options: List[String], error: String => Unit): Boolean = { for (option <- options) { if (option.startsWith("log-level:")) { option.substring("log-level:".length).toLowerCase match { case "info" => logLevel = LogLevel.Info case "warn" => logLevel = LogLevel.Warn case "error" => logLevel = LogLevel.Error case other => error(s"Unexpected log level value: '$other'") } } else { error(s"Unrecognised option: $option") } } true } val components = List( new NamedHolesComponent(this, global), new TypedHolesComponent(this, global, () => logLevel) ) }
Example 24
Source File: NamedHolesComponent.scala From scala-typed-holes with Apache License 2.0 | 5 votes |
package holes import scala.tools.nsc.{Global, Phase} import scala.tools.nsc.transform.Transform import scala.tools.nsc.ast.TreeDSL import scala.tools.nsc.plugins.{Plugin, PluginComponent} class NamedHolesComponent(plugin: Plugin, val global: Global) extends PluginComponent with TreeDSL with Transform { override val phaseName: String = "named-holes" override val runsAfter: List[String] = List("parser") override val runsBefore: List[String] = List("namer") import global._ override def newTransformer(unit: CompilationUnit): Transformer = new NamedHolesTransformer(unit) class NamedHolesTransformer(unit: CompilationUnit) extends Transformer { object NamedHole { val pattern = "^__([a-zA-Z0-9_]+)$".r def unapply(name: Name): Option[String] = pattern.unapplySeq(name.decoded.toString).flatMap(_.headOption) } override def transform(tree: Tree): Tree = { val t = super.transform(tree) t match { case Ident(NamedHole(name)) => atPos(t.pos)(treeCopy.Ident(t, TermName("$qmark$qmark$qmark"))) .updateAttachment(HoleName(name)) case _ => t } } } }
Example 25
Source File: NoMapIdentity.scala From better-monadic-for with MIT License | 5 votes |
package com.olegpy.bm4 import scala.reflect.internal.{Definitions, ModifierFlags, SymbolTable} import scala.tools.nsc.Global import scala.tools.nsc.ast.TreeDSL import scala.tools.nsc.transform.TypingTransformers trait NoMapIdentity extends TreeUtils { import global._ def noMapIdentity: Boolean object NoMapIdentity { def unapply(tree: Tree): Option[Tree] = tree match { case _ if !noMapIdentity => None // plain monomorphic map case q"${sel @ q"$body.map"}[..$_](${IdentityFunction()})" if sel.hasAttachment[ForAttachment.type] && tree.tpe =:= body.tpe => Some(replaceTree(tree, body)) // map with implicit parameters case q"${sel @ q"$body.map"}[..$_](${IdentityFunction()})(..$_)" if sel.hasAttachment[ForAttachment.type] && tree.tpe =:= body.tpe => Some(replaceTree(tree, body)) // map on implicit conversion with implicit parameters (e.g. simulacrum ops) case q"${sel @ q"$_($body)(..$_).map"}[..$_](${IdentityFunction()})" if sel.hasAttachment[ForAttachment.type] && body.tpe.widen =:= tree.tpe // body.tpe will be inferred to singleton type => Some(replaceTree(tree, body)) case _ => None } } object IdentityFunction { def unapply(tree: Tree): Boolean = tree match { case Function(ValDef(mods, TermName(x), tpt, _) :: Nil, i @ Ident(TermName(x2))) if (x == x2) && mods.flags == ModifierFlags.PARAM && (i.tpe =:= tpt.tpe) => true case Function(ValDef(_, _, tpt, EmptyTree) :: Nil, LiteralUnit(u)) if tpt.tpe =:= definitions.UnitTpe && tpt.tpe =:= u.tpe => true case _ => false } } object LiteralUnit { def unapply(tree: Tree): Option[Tree] = tree match { case u @ Literal(Constant(())) => Some(u) // In Scala 2:13, we get `(x$1: Unit @unchecked) match { case _ => () }` case u @ Match(Typed(Ident(TermName(x)), tpt), List( CaseDef(Ident(termNames.WILDCARD), EmptyTree, Literal(Constant(()))))) if tpt.tpe =:= definitions.UnitTpe => Some(u) case _ => None } } }
Example 26
Source File: CompilerSetup.scala From perf_tester with Apache License 2.0 | 5 votes |
package benchmarks import java.io.File import java.nio.file.{Files, Path} import benchmarks.Main.rootPath import scala.reflect.internal.util.Position import scala.tools.nsc.{Global, Settings} import scala.tools.nsc.reporters.Reporter import scala.util.Try import collection.JavaConverters._ case class CompilerSetup(rootPath: Path, providedScalacOptions: List[String]) { val outputDir: Path = rootPath.resolve("output") val currentOutput: Path = outputDir.resolve("classes") val scalacOptions = providedScalacOptions ++ Try(Files.readAllLines(rootPath.resolve("scalac.opts")).asScala.flatMap(_.split(" +"))).getOrElse(Nil) IO.cleanDir(outputDir) Files.createDirectories(currentOutput) val cpJars = IO.jarsIn(rootPath.resolve("cpJars")) val reporter: Reporter = new Reporter { // We are ignoring all override protected def info0(pos: Position, msg: String, severity: this.Severity, force: Boolean): Unit = { // println(s"[$severity] $pos: $msg") // Uncomment for to get compilation messages } } val settings: Settings = new Settings( msg => throw new RuntimeException(s"[ERROR] $msg") ) configure(settings) val global: Global = new Global(settings, reporter) def configure(settings: Settings): Unit = { settings.outputDirs.setSingleOutput(currentOutput.toAbsolutePath.toString) settings.classpath.append(cpJars.mkString(File.pathSeparator)) settings.processArguments(scalacOptions, processAll = true) } }
Example 27
Source File: IntegrationTest.scala From scala-sculpt with Apache License 2.0 | 5 votes |
// Copyright (C) 2015-2020 Lightbend Inc. <http://lightbend.com> package com.lightbend.tools.sculpt import scala.tools.nsc.{ Settings, Global } import scala.tools.nsc.io.VirtualDirectory import scala.reflect.internal.util.BatchSourceFile object Scaffold { val classes: String = { // this will be e.g. "2.11" or "2.12" val majorScalaVersion = { val v = scala.util.Properties.versionNumberString if (v matches ".*-(pre-\\w+|M\\d+|RC\\d+)") { v } else { v.split('.').take(2).mkString(".") } } val relative = s"./target/scala-$majorScalaVersion/classes" val file = new java.io.File(relative) assert(file.exists) file.getAbsolutePath } def defaultSettings: Settings = { val settings = new Settings settings.processArgumentString( s"-usejavacp -Xplugin:$classes -Xplugin-require:sculpt") settings.outputDirs.setSingleOutput( new VirtualDirectory("(memory)", None)) settings } def analyze(code: String, classMode: Boolean = false): String = { val out = java.io.File.createTempFile("sculpt", "json", null) val modeSetting = if (classMode) " -P:sculpt:mode=class" else "" val settings = defaultSettings settings.processArgumentString(s"-P:sculpt:out=$out$modeSetting") val sources = List(new BatchSourceFile("<test>", code)) val compiler = new Global(settings) (new compiler.Run).compileSources(sources) scala.io.Source.fromFile(out).mkString } } class IntegrationTest extends munit.FunSuite { def check(s: Sample): Unit = { assert(s.json == Scaffold.analyze(s.source)) assert(s.classJson == Scaffold.analyze(s.source, classMode = true)) } for (sample <- Samples.samples) test(sample.name) { check(sample) } }