diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala index f0c0701..5453778 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala @@ -1,41 +1,84 @@ package org.canve.compilerPlugin import tools.nsc.Global -case class ExtractedSymbol - (symbolCompilerId: SymbolCompilerId, - name: String, - kind: String, - qualifiedId: QualifiedID, +class ExtractedSymbol( + + /* + * the symbol id drawn from the compiler - only guaranteed to be unique within a single + * compilation, meaning a single project's compilation + */ + val symbolCompilerId: SymbolCompilerId, - signatureString: Option[String] = None, + /* symbol's name, or None if the symbol is anonymous */ + val name: Option[String], - notSynthetic: Boolean, - definingProject: DefiningProject) extends SymbolSerialization { + /* symbol's kind - package, class, object, method, etc.. */ + val kind: String, + + /* an identifier similar to Java's FQN, to help uniquely identify a symbol across projects */ + val qualifyingPath: QualifyingPath, + + /* symbol's type signature, as a string */ + val signatureString: Option[String] = None, + + /* + * this is a delicate definition, will likely receive a finer definition going forward. + * informally speaking it marks whether the symbol is a contrived one added by the compiler, + * or just a regular one very directly associated to a source code element. + */ + val nonSynthetic: Boolean, + + /* + * says whether the symbol's implementation is defined in the current project, or externally to it. + * for example a symbol may be one that has its implementation coming from a library, or from a depended-upon + * subproject summoned into the compilation classpath by sbt or other tool. In those cases, this marks that + * the symbol's implementation resides externally, not within the project being compiled. + */ + val implementation: ImplementationLoc) - val qualifiedIdAndSignature: FurtherQualifiedID = - qualifiedId.pickle + (signatureString match { - case Some(s) => " * " + s - case None => "" - }) - - def definitionCode(implicit extractedModel: ExtractedModel): Option[Code] = - extractedModel.codes.get.get(symbolCompilerId) + extends SymbolSerialization { + + /* getter for symbol's code description, the latter kept in a separate collection */ + def definitionCode(implicit extractedModel: ExtractedModel): Option[Code] = + extractedModel.codes.get.get(symbolCompilerId) - /* more inclusive serialization for this class - for logging */ - override def toString = - List(symbolCompilerId, - name, - kind, - qualifiedId, - signatureString, - notSynthetic, - definingProject, - qualifiedIdAndSignature).map(_.toString).mkString(",") + /* more inclusive serialization for this class - for logging */ + override def toString = + List(symbolCompilerId, + name, + kind, + qualifyingPath, + signatureString, + nonSynthetic, + implementation).map(_.toString).mkString(",") - /* symbol and its code info joined into a string - for logging */ - def toJoinedString(implicit extractedModel: ExtractedModel) = toString + ",code: " + definitionCode.toString + /* symbol and its code info joined into a string - for logging */ + def toJoinedString(implicit extractedModel: ExtractedModel) = toString + ",code: " + definitionCode.toString - var ownersTraversed = false + var ownersTraversed = false +} + +object ExtractedSymbol { + + /* + * just the obvious apply, to provide a case class instantiation style + */ + def apply( + symbolCompilerId: SymbolCompilerId, + name: Option[String], + kind: String, + qualifyingPath: QualifyingPath, + signatureString: Option[String], + nonSynthetic: Boolean, + implementation: ImplementationLoc) = + new ExtractedSymbol( + symbolCompilerId, + name, + kind, + qualifyingPath, + signatureString, + nonSynthetic, + implementation) } /* @@ -60,16 +103,24 @@ case class Point(init: Int) extends Position { def apply = init } /* * types for whether a symbol is defined in * the current project, or is an external one + * being referenced by this project */ - -abstract class DefiningProject -object ProjectDefined extends DefiningProject -object ExternallyDefined extends DefiningProject +abstract class ImplementationLoc +object ProjectDefined extends ImplementationLoc +object ExternallyDefined extends ImplementationLoc /* - * a lame join type of a symbol and its extracted code, wherever helpful + * case class and companion */ +case class FQI(qPath: QualifyingPath, signatureString: Option[String]) +object FQI { + def apply(s: ExtractedSymbol) = new FQI(s.qualifyingPath, s.signatureString) +} + +/* + * a lame join type of a symbol and its extracted code, if helpful + */ case class SymbolCodeJoin( extractedModel: ExtractedModel, symbol: ExtractedSymbol) { diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala index c5ac573..15d5f07 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala @@ -23,32 +23,34 @@ class ExtractedModel(global: Global) extends ContainsExtractedGraph { def add(global: Global)(s: global.Symbol): ExtractedSymbol = { graph.vertex(s.id) match { + case Some(v: graph.Vertex) => //throw ExtractionException(s"graph already has symbol with id ${s.id}") TraversalSymbolRevisit.increment v.data + case None => - val qualifiedId = QualifiedID.compute(global)(s) + val qualifyingPath = QualifyingPath(global)(s) /* * determine whether the symbol at hand is defined in the current project, */ - val definingProject = s.sourceFile match { - case null => ExternallyDefined // no source file included in this project for this entity + val implementation = s.sourceFile match { + case null => ExternallyDefined // no source file for this entity = external symbol case _ => ProjectDefined } - + /* * add the symbol to the extracted model */ val extractedSymbol = ExtractedSymbol( symbolCompilerId = s.id, - name = s.nameString, + name = maybeName(global)(s), kind = s.kindString, - qualifiedId = qualifiedId, - notSynthetic = !(s.isSynthetic), - definingProject = definingProject, + qualifyingPath = qualifyingPath, + nonSynthetic = !(s.isSynthetic), + implementation = implementation, signatureString = s.signatureString match { case("<_>") => None case signatureString@_ => Some(signatureString) @@ -60,7 +62,7 @@ class ExtractedModel(global: Global) extends ContainsExtractedGraph { * pass on to attempt to extract the symbol's source code, * if it is defined in the current project */ - definingProject match { + implementation match { case ProjectDefined => codes(global)(s, AttemptCodeExtract(global)(s)) case ExternallyDefined => // no source file included in this project for this entity } diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Output.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Output.scala index 4d4415c..77b3ed6 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Output.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Output.scala @@ -10,7 +10,7 @@ object Output { Log(s"writing extracted type relations and call graph for project ${PluginArgs.projectName}...") writeOutputFile(PluginArgs.projectName, "symbols", - "definition,notSynthetic,id,name,kind,qualifiedId,signature\n" + + "implementation,nonSynthetic,id,name,kind,qualifiedId,signature\n" + (extractedModel.graph.vertexIterator.map(_.data.toCsvRow)).mkString("\n")) println("before output") diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualiferID.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualiferID.scala deleted file mode 100644 index 74c1431..0000000 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualiferID.scala +++ /dev/null @@ -1,44 +0,0 @@ -package org.canve.compilerPlugin -import tools.nsc.Global - -/* - * Unique Symbol QualiferID, serializable - */ -case class KindAndName(kind: String, name: String) -object KindAndName { - def apply(global: Global)(s: global.Symbol): KindAndName = { - new KindAndName(s.kindString, s.nameString) - } -} - -case class QualifiedID(value: List[KindAndName]) { - def pickle = value.map(kindAndName => "(" + kindAndName.kind + "|" + kindAndName.name + ")").mkString(".") -} -object QualifiedID { - - def compute(global: Global)(s: global.Symbol): QualifiedID = { - val kindNameList: List[KindAndName] = - s.ownerChain.reverse.map(owner => KindAndName(global)(owner)) - - assert(kindNameList.head.kind == "package") - assert(kindNameList.head.name == "") - - /* - * TODO: remove this commented out code - * - (s.kindString == "method") match { - case true => - val paramListList: List[List[global.Symbol]] = s.paramss - QualifiedID(kindNameList.drop(1) ++ s.paramss.flatten.map(p => KindAndName(global)(p))) - case false => - QualifiedID(kindNameList.drop(1)) - } - */ - - QualifiedID(kindNameList.drop(1)) - - } - - def unpickle(s: String) = - QualifiedID(s.split('.').toList.map(pair => KindAndName(pair.takeWhile(_!='|').drop(1), pair.dropWhile(_!='|').drop(1).dropRight(1)))) -} diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualifyingPath.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualifyingPath.scala new file mode 100644 index 0000000..144bc4b --- /dev/null +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/QualifyingPath.scala @@ -0,0 +1,60 @@ +package org.canve.compilerPlugin +import tools.nsc.Global +import Util._ + +/* + * A Qualified Identification of a symbol, that does not rely on its compiler assigned id, + * is useful for correlating symbols across project boundaries. Here we provide the necessary class + * for creating and using such an identification, which we will call for brevity QI. + */ + +/* The class and factory */ + +case class QualifyingPath(value: List[QualificationUnit]) { + + /* + * if any anonymous object is part of the qualification chain, then (by definition) the + * chain cannot be considered by any means unique - anonymous objects may sit side-by-side + * under the same program context, and having no name, cannot be easily differentiated. + */ + val fullyNamed: Boolean = value.forall(_.name.isDefined) + + def pickle = value.map(kindAndName => "(" + kindAndName.kind + "|" + kindAndName.name + ")").mkString(".") +} + +/* + * companion object providing both a constructor from a global.symbol and + * a constructor from string-pickled input + */ +object QualifyingPath { + + def apply(s: String): QualifyingPath = + QualifyingPath(s.split('.').toList.map(s => + QualificationUnit( + s.takeWhile(_!='|').drop(1), + deSerializeOption[String](s) match { + case None => None + case Some(s) => Some(s.dropWhile(_!='|').drop(1).dropRight(1)) + }))) + + def apply(global: Global)(s: global.Symbol): QualifyingPath = { + val kindNameList: List[QualificationUnit] = + s.ownerChain.reverse.map(owner => QualificationUnit(global)(owner)) + + assert(kindNameList.head.kind == "package") + assert(kindNameList.head.name.get == "") + + QualifyingPath(kindNameList.drop(1)) + } +} + + +/* auxiliary class and factory */ + +case class QualificationUnit(kind: String, name: Option[String]) + +object QualificationUnit { + def apply(global: Global)(s: global.Symbol): QualificationUnit = { + new QualificationUnit(s.kindString, maybeName(global)(s)) + } +} diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala index d4d1add..5c2c8ea 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala @@ -9,14 +9,14 @@ trait SymbolSerialization { def toCsvRow(implicit extractedModel: ExtractedModel): String = { // Note: escaping for csv is for now handled here by hand (likely a tad faster) List( - definingProject match { + implementation match { case ProjectDefined => "project" case ExternallyDefined => "external" }, - notSynthetic, + nonSynthetic, symbolCompilerId, name, kind, - qualifiedId.pickle, + qualifyingPath.pickle, "\"" + signatureString + "\"" // escaped as it contains, typically, commas ).mkString(",") } @@ -29,12 +29,12 @@ object SymbolFromCsvRow { import Util._ def apply(projectName: String, rowMap: Map[String, String]): ExtractedSymbol = { ExtractedSymbol(symbolCompilerId = rowMap("id").toInt, - name = rowMap("name"), + name = deSerializeOption(rowMap("name")), kind = rowMap("kind"), - notSynthetic = rowMap("notSynthetic").toBoolean, - qualifiedId = QualifiedID.unpickle(rowMap("qualifiedId")), + nonSynthetic = rowMap("nonSynthetic").toBoolean, + qualifyingPath = QualifyingPath(rowMap("qualifiedId")), signatureString = deSerializeOption(rowMap("signature")), - definingProject = rowMap("definition") match { + implementation = rowMap("implementation") match { case "project" => ProjectDefined case "external" => ExternallyDefined }) diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/CrossProjectNormalize.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/CrossProjectNormalize.scala index 8e2cc64..ae2398c 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/CrossProjectNormalize.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/CrossProjectNormalize.scala @@ -1,4 +1,5 @@ -package org.canve.compilerPlugin +package org.canve.compilerPlugin.normalization +import org.canve.compilerPlugin._ import org.canve.util.CanveDataIO._ import com.github.tototoshi.csv._ import java.io.File @@ -12,7 +13,7 @@ import org.canve.simpleGraph._ trait DataReader { type LoadedGraph = SimpleGraph[SymbolCompilerId, ExtractedSymbol, ExtractedSymbolRelation] - type ReIndexedGraph = SimpleGraph[FurtherQualifiedID, ExtractedSymbol, ExtractedSymbolRelation] + type ReIndexedGraph = SimpleGraph[FQI, ExtractedSymbol, ExtractedSymbolRelation] /* * builds graph from a canve data directory @@ -49,22 +50,28 @@ trait DataReader { } } -object CrossProjectNormalizer extends DataReader { +object CrossProjectNormalizer extends DataReader with MergeStrategies { def apply = normalize def normalize: ReIndexedGraph = { - val projectGraphs: Iterator[LoadedGraph] = - getSubDirectories(canveRoot).toIterator.map(readCanveDirData) + /* iterator of tuples (directory name, read graph) */ + val projectGraphs = + getSubDirectories(canveRoot).toIterator.map(subDirectory => (subDirectory.getName, readCanveDirData(subDirectory))) val aggregateGraph = new ReIndexedGraph - projectGraphs.foreach { graph => + // TODO: make / refactor this to avoid ever merging stuff from same project + + projectGraphs.foreach { iterator => + + val (projectName, graph) = iterator + graph.vertexIterator.foreach { v => val symbol = v.data - aggregateGraph.vertex(symbol.qualifiedIdAndSignature) match { + aggregateGraph.vertex(FQI(symbol)) match { - case None => aggregateGraph ++ aggregateGraph.Vertex(key = symbol.qualifiedIdAndSignature, data = symbol) + case None => aggregateGraph ++ aggregateGraph.Vertex(key = FQI(symbol), data = symbol) case Some(v) => maybeMerge(aggregateGraph, aggregateGraphSymbol = v.data, sameKeyedSymbol = symbol) @@ -75,6 +82,9 @@ object CrossProjectNormalizer extends DataReader { aggregateGraph } + /* + * + */ private def maybeMerge( aggregateGraph: ReIndexedGraph, aggregateGraphSymbol: ExtractedSymbol, @@ -82,16 +92,22 @@ object CrossProjectNormalizer extends DataReader { assertSimilarity(aggregateGraphSymbol, sameKeyedSymbol) - (aggregateGraphSymbol.definingProject, sameKeyedSymbol.definingProject) match { + (aggregateGraphSymbol.implementation, sameKeyedSymbol.implementation) match { - case (ProjectDefined, ExternallyDefined) => // do nothing - case (ExternallyDefined, ExternallyDefined) => // do nothing - + case (ProjectDefined, ExternallyDefined) => + // do not add new symbol to aggregate graph, thus de-duplicating it + // TODO: !! handle its edges re-wire though! + println(s"deduplicated one symbol: $sameKeyedSymbol") + case (ExternallyDefined, ProjectDefined) => - aggregateGraph -- aggregateGraphSymbol.qualifiedIdAndSignature - aggregateGraph ++ aggregateGraph.Vertex(key = sameKeyedSymbol.qualifiedIdAndSignature, data = sameKeyedSymbol) - println("deduplicated one node") - + // replace externally defined symbol with the new one, thus de-duplicating it + aggregateGraph -- FQI(aggregateGraphSymbol) + aggregateGraph ++ aggregateGraph.Vertex(key = FQI(sameKeyedSymbol), data = sameKeyedSymbol) + // TODO: handle the edges re-wire! + println(s"deduplicated one symbol: $aggregateGraphSymbol") + + case (ExternallyDefined, ExternallyDefined) => // do nothing, or rather merge to single ExternallyDefined one? + case (ProjectDefined, ProjectDefined) => // TODO: This exception message doesn't help zoom in on the project names without logs excavation. // Might be solved by adding the project name to each symbol being compared, somewhere before. @@ -105,8 +121,8 @@ object CrossProjectNormalizer extends DataReader { private def assertSimilarity(s1: ExtractedSymbol, s2: ExtractedSymbol) { if (s1.name == s2.name) if (s1.kind == s2.kind) - if (s1.notSynthetic == s2.notSynthetic) - if (s1.qualifiedId == s2.qualifiedId) + if (s1.nonSynthetic == s2.nonSynthetic) + if (s1.qualifyingPath == s2.qualifyingPath) return println(DataNormalizationException( diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeSameSpanSymbols.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeSameSpanSymbols.scala index 4e352b9..1cf8f84 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeSameSpanSymbols.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeSameSpanSymbols.scala @@ -11,18 +11,18 @@ object MergeSameSpanSymbols extends MergeSameSpanSymbols trait MergeSameSpanSymbols extends MergeStrategies { - /* Future logging/exception classes */ + /* Logging classes */ case class SpansDefer(extractedSymbols: (ExtractedSymbol, ExtractedSymbol))(implicit extractedModel: ExtractedModel) { def apply() = - s"""(${this.getClass.getSimpleName}:) Data normalization unexpected inconsistency encountered - two symbols assumed to be the same one ID have different source extraction spans: + s"""(${this.getClass.getSimpleName}:) Info: samely qualified symbols have different source extraction spans: |${extractedSymbols._1.toJoinedString} |${extractedSymbols._2.toJoinedString}""".stripMargin } case class StartPositionsDefer(extractedSymbols: (ExtractedSymbol, ExtractedSymbol))(implicit extractedModel: ExtractedModel) { def apply() = - s"""${this.getClass.getSimpleName}:) Data normalization unexpected inconsistency encountered - two symbols assumed to be the same one ID have different source location start position: + s"""${this.getClass.getSimpleName}:) Info: samely qualified symbols have different source location start positions: |${extractedSymbols._1.toJoinedString} |${extractedSymbols._2.toJoinedString}""".stripMargin } @@ -41,17 +41,12 @@ trait MergeSameSpanSymbols extends MergeStrategies { def logMerge(extractedSymbols: (ExtractedSymbol, ExtractedSymbol), comment: Option[String]) = { val message = - s"""merging symbol pair ${comment.getOrElse()}: + s"""merging symbol pair ${comment.getOrElse("")}: |${extractedSymbols._1.toJoinedString} |${extractedSymbols._2.toJoinedString}""".stripMargin println(message) } - - @deprecated def pointOrStart(location: Position): Option[Int] = location match { - case Span(start, end) => Some(start) - case Point(loc) => Some(loc) - } /* * Is a point location reasonably within bounds of given span? @@ -65,18 +60,18 @@ trait MergeSameSpanSymbols extends MergeStrategies { /* - * Merge project-defined synthetic symbols + * Merge project-defined synthetic symbols within the current source file which: + * have the same qualifying path, but not necessarily the same signature string */ extractedModel.graph.vertexIterator // group extracted symbols - project defined synthetic ones only - .filter(v => !v.data.notSynthetic && v.data.definingProject == ProjectDefined) - .toList.groupBy(m => m.data.qualifiedId) + .filter(v => !v.data.nonSynthetic && v.data.implementation == ProjectDefined) + .toList.groupBy(v => v.data.qualifyingPath) .foreach { bin => val symbolBin = bin._2 assert(symbolBin.forall(v => v.data.definitionCode.get.code.isEmpty)) // synthetic symbols aren't expected to have code definitions if (symbolBin.size > 2) { - println(symbolBin.size) symbolBin.foreach(v => println(v.data.toJoinedString)) throw DataNormalizationException(s"Unexpected amount of mergeable symbols for single source location: ${symbolBin.map(_.data.toJoinedString)}") } @@ -90,12 +85,16 @@ trait MergeSameSpanSymbols extends MergeStrategies { } /* - * Merge project-defined non-synthetic symbols + * Merge project-defined non-synthetic symbols within the current source file which: + * + * 1. have the same qualifying path + * 2. have the same signature string + * 3. sufficiently overlap in their location of definition in the current source file */ extractedModel.graph.vertexIterator // first off, group extracted symbols - project defined non-synthetic ones only - .filter(v => v.data.notSynthetic && v.data.definingProject == ProjectDefined) - .toList.groupBy(m => m.data.qualifiedIdAndSignature) + .filter(v => v.data.nonSynthetic && v.data.implementation == ProjectDefined) + .toList.groupBy(v => FQI(v.data)) .foreach { bin => val symbolBin = bin._2 if (symbolBin.size > 2) { @@ -110,8 +109,8 @@ trait MergeSameSpanSymbols extends MergeStrategies { val definingCodes: (Code, Code) = (extractedSymbols._1.definitionCode.get, extractedSymbols._2.definitionCode.get) /* - * do the symbols sharing the same qualified ID come from the exact same source code - * definition? we check that by comparing the location of their definition + * do the symbols sharing the same FQI also share the exact same + * location of definition in the source code? */ assert (definingCodes._1.location.path == definingCodes._1.location.path) // should come from the same source file @@ -120,18 +119,18 @@ trait MergeSameSpanSymbols extends MergeStrategies { // The case of two spans -> are they the same? case (Some(Span(start1, end1)), Some(Span(start2, end2))) => - if (start1 == start2 && end1 == end2) doMerge(symbolBin) - else println(SpansDefer(extractedSymbols).apply) // TODO: refer to dedicated log file that holds all cases + if (start1 == start2 && end1 == end2) doMerge(symbolBin, Some("non synthetics, equal spans")) + else println(SpansDefer(extractedSymbols).apply) // The case of a span and a point position -> do they share the same start position? case (Some(Span(spanStart, spanEnd)), Some(Point(start))) => - if (spanStart == start || pointWithinSpan(spanStart, spanEnd, start)) doMerge(symbolBin) - else println(StartPositionsDefer(extractedSymbols).apply) // TODO: refer to dedicated log file that holds all cases + if (spanStart == start || pointWithinSpan(spanStart, spanEnd, start)) doMerge(symbolBin, Some("both non synthetics, point within span")) + else println(StartPositionsDefer(extractedSymbols).apply) // Same, but appearing in reverse order case (Some(Point(start)), Some(Span(spanStart, spanEnd))) => - if (spanStart == start || pointWithinSpan(spanStart, spanEnd, start)) doMerge(symbolBin.reverse) - else println(StartPositionsDefer(extractedSymbols).apply) // TODO: refer to dedicated log file that holds all cases + if (spanStart == start || pointWithinSpan(spanStart, spanEnd, start)) doMerge(symbolBin.reverse, Some("both non synthetics, point within span")) + else println(StartPositionsDefer(extractedSymbols).apply) case x@(Some(Point(point1)), Some(Point(point2))) => println(s"""Info: two symbols assumed to be the same entity both have only a position location: $x""") diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeStrategies.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeStrategies.scala index 45589eb..82715e2 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeStrategies.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/normalization/MergeStrategies.scala @@ -6,9 +6,8 @@ import org.canve.simpleGraph._ * a home for various vertices merger strategies */ -trait MergeStrategies extends { - self: MergeSameSpanSymbols => - +trait MergeStrategies { + /* * Merges a list of vertices to its head vertex, collapsing all their * edges to the head vertex. diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/package.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/package.scala index 0527bbe..6851b55 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/package.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/package.scala @@ -2,6 +2,7 @@ package org.canve import org.canve.simpleGraph._ import org.canve.simpleGraph.algo.impl.GetPathsBetween +import tools.nsc.Global package object compilerPlugin { @@ -22,5 +23,13 @@ package object compilerPlugin { val graph = new ManagedExtractedGraph with GetPathsBetween[SymbolCompilerId, ExtractedSymbol, ExtractedSymbolRelation] - } + } + + def maybeName(global: Global)(s: global.Symbol): Option[String] = { + (s.isAnonymousClass || s.isAnonymousFunction) match { + case true => None + case false => Some(s.nameString) + } + } + } \ No newline at end of file diff --git a/compiler-plugin/src/test/scala/Instantiaion.scala b/compiler-plugin/src/test/scala/Instantiaion.scala index 275dbab..a9039c8 100644 --- a/compiler-plugin/src/test/scala/Instantiaion.scala +++ b/compiler-plugin/src/test/scala/Instantiaion.scala @@ -101,9 +101,9 @@ object InstantiationTester extends TraversalExtractionTester with NodeSearch { * utility function for compact printing of symbols' qualified id */ def shortDescription(symbol: ExtractedSymbol) = { - val shortenedQualifiedId = (symbol.qualifiedId.value.head.name match { - case "" => symbol.qualifiedId.value.drop(1) - case _ => symbol.qualifiedId.value + val shortenedQualifiedId = (symbol.qualifyingPath.value.head.name match { + case "" => symbol.qualifyingPath.value.drop(1) + case _ => symbol.qualifyingPath.value }).map(_.name).mkString(".") s"${symbol.kind} $shortenedQualifiedId (${symbol.symbolCompilerId})" diff --git a/sbt-plugin/src/main/scala/canve/sbt/sbtPlugin.scala b/sbt-plugin/src/main/scala/canve/sbt/sbtPlugin.scala index 654bdf7..36eb9ca 100644 --- a/sbt-plugin/src/main/scala/canve/sbt/sbtPlugin.scala +++ b/sbt-plugin/src/main/scala/canve/sbt/sbtPlugin.scala @@ -121,7 +121,7 @@ object Plugin extends AutoPlugin { successfulProjects.length == extracted.structure.allProjectRefs.length match { case true => println("normalizing data across subprojects...") - val normalizedData = org.canve.compilerPlugin.CrossProjectNormalizer.apply + val normalizedData = org.canve.compilerPlugin.normalization.CrossProjectNormalizer.apply println("canve task done") state case false =>