From 721f2d67a3cd0dc904bdf53d3e0177e056b6009b Mon Sep 17 00:00:00 2001 From: matan Date: Sat, 5 Dec 2015 22:08:14 +0200 Subject: [PATCH] commit demonstrating https://github.com/CANVE/extractor/issues/8 --- .../canve/compilerPlugin/DataClasses.scala | 27 ++++++++++++++----- .../canve/compilerPlugin/ExtractedModel.scala | 13 ++++++--- .../canve/compilerPlugin/Serialization.scala | 4 +-- .../compilerPlugin/TraversalExtraction.scala | 8 +++--- .../normalization/CrossProjectNormalize.scala | 8 +++--- 5 files changed, 41 insertions(+), 19 deletions(-) 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 5453778..884a2bf 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/DataClasses.scala @@ -1,6 +1,19 @@ package org.canve.compilerPlugin import tools.nsc.Global +case class ExtractedSymbolPlus(e: ExtractedSymbol, val implementingProject: String) + extends ExtractedSymbol( + e.symbolCompilerId, + e.name, + e.kind, + e.qualifyingPath, + e.signatureString, + e.nonSynthetic, + e.implementation) { + + override def toString = s"${super.toString}, $implementingProject}" +} + class ExtractedSymbol( /* @@ -10,7 +23,7 @@ class ExtractedSymbol( val symbolCompilerId: SymbolCompilerId, /* symbol's name, or None if the symbol is anonymous */ - val name: Option[String], + val name: SymbolName, /* symbol's kind - package, class, object, method, etc.. */ val kind: String, @@ -34,9 +47,7 @@ class ExtractedSymbol( * 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) - - extends SymbolSerialization { + val implementation: ImplementationLoc) extends SymbolSerialization { /* getter for symbol's code description, the latter kept in a separate collection */ def definitionCode(implicit extractedModel: ExtractedModel): Option[Code] = @@ -55,7 +66,7 @@ class ExtractedSymbol( /* 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 // TODO: not needed by those that inherit, so further refactor to base class that excludes this var } object ExtractedSymbol { @@ -65,7 +76,7 @@ object ExtractedSymbol { */ def apply( symbolCompilerId: SymbolCompilerId, - name: Option[String], + name: SymbolName, kind: String, qualifyingPath: QualifyingPath, signatureString: Option[String], @@ -81,6 +92,10 @@ object ExtractedSymbol { implementation) } +class SymbolName(name: String) +case class RealName(name: String) extends SymbolName(name) +case class DeAnonimizedName(name: String) extends SymbolName(name) + /* * symbol's extracted source code location and content */ 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 15d5f07..00e8203 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/ExtractedModel.scala @@ -39,14 +39,17 @@ class ExtractedModel(global: Global) extends ContainsExtractedGraph { 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 = maybeName(global)(s), + name = maybeName(global)(s) match { + case None => DeAnonimizedName(s.pos.hashCode.toHexString) + case Some(s) => RealName(s) + }, kind = s.kindString, qualifyingPath = qualifyingPath, nonSynthetic = !(s.isSynthetic), @@ -64,7 +67,9 @@ class ExtractedModel(global: Global) extends ContainsExtractedGraph { */ implementation match { case ProjectDefined => codes(global)(s, AttemptCodeExtract(global)(s)) - case ExternallyDefined => // no source file included in this project for this entity + case ExternallyDefined => + println(s"""external symbol's pos details follow. symbol: $s, source: ${s.sourceFile} ${s.pos.line} ${s.pos.column}""".stripMargin) + // no source file included in this project for this entity } normalization.CompleteOwnerChain(global)(extractedSymbol, s, this) @@ -88,7 +93,7 @@ class ExtractedCodes { def apply(global: Global)(s: global.Symbol, code: Code) = { map.contains(s.id) match { case false => map += (s.id -> code) - case true => // do nothing + case true => // do nothing, for now } } 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 5c2c8ea..62fd9d7 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/Serialization.scala @@ -14,7 +14,7 @@ trait SymbolSerialization { case ExternallyDefined => "external" }, nonSynthetic, symbolCompilerId, - name, + name, // TODO: serialize harmoniously to the reader below and code that uses it kind, qualifyingPath.pickle, "\"" + signatureString + "\"" // escaped as it contains, typically, commas @@ -29,7 +29,7 @@ object SymbolFromCsvRow { import Util._ def apply(projectName: String, rowMap: Map[String, String]): ExtractedSymbol = { ExtractedSymbol(symbolCompilerId = rowMap("id").toInt, - name = deSerializeOption(rowMap("name")), + name = new SymbolName(rowMap("name")), // TODO: this is not the correct way to deserialize the field as outputted kind = rowMap("kind"), nonSynthetic = rowMap("nonSynthetic").toBoolean, qualifyingPath = QualifyingPath(rowMap("qualifiedId")), diff --git a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/TraversalExtraction.scala b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/TraversalExtraction.scala index 03da1cb..dad96c4 100644 --- a/compiler-plugin/src/main/scala/org/canve/compilerPlugin/TraversalExtraction.scala +++ b/compiler-plugin/src/main/scala/org/canve/compilerPlugin/TraversalExtraction.scala @@ -42,8 +42,9 @@ object TraversalExtraction { } // record the source code location where the symbol is being used by the user - // this is a proof of concept, that only doesn't propagate its information - // to the UI in any way yet. + // this is a proof of concept, that only writes to the log for now. + // needs to happen not just for method calls but also for object usage and whatever else - + // so that fully linked source code display has its data if (defParent.isDefined) { val callingSymbol = defParent.get callingSymbol.sourceFile match { @@ -53,7 +54,8 @@ object TraversalExtraction { val source = callingSymbol.sourceFile.toString val line = select.pos.line val column = select.pos.column - //Log("symbol " + select.symbol.nameString + "is being used in " + source + " " + line + "," + column) + Log(s"""symbol ${select.symbol.nameString} is being used by $callingSymbol in $source ($line, $column):" + |$source""".stripMargin) } } 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 ae2398c..44060c3 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 @@ -13,7 +13,7 @@ import org.canve.simpleGraph._ trait DataReader { type LoadedGraph = SimpleGraph[SymbolCompilerId, ExtractedSymbol, ExtractedSymbolRelation] - type ReIndexedGraph = SimpleGraph[FQI, ExtractedSymbol, ExtractedSymbolRelation] + type ReIndexedGraph = SimpleGraph[FQI, ExtractedSymbolPlus, ExtractedSymbolRelation] /* * builds graph from a canve data directory @@ -68,7 +68,7 @@ object CrossProjectNormalizer extends DataReader with MergeStrategies { val (projectName, graph) = iterator - graph.vertexIterator.foreach { v => val symbol = v.data + graph.vertexIterator.foreach { v => val symbol = ExtractedSymbolPlus(v.data, projectName) aggregateGraph.vertex(FQI(symbol)) match { case None => aggregateGraph ++ aggregateGraph.Vertex(key = FQI(symbol), data = symbol) @@ -87,8 +87,8 @@ object CrossProjectNormalizer extends DataReader with MergeStrategies { */ private def maybeMerge( aggregateGraph: ReIndexedGraph, - aggregateGraphSymbol: ExtractedSymbol, - sameKeyedSymbol: ExtractedSymbol) = { + aggregateGraphSymbol: ExtractedSymbolPlus, + sameKeyedSymbol: ExtractedSymbolPlus) = { assertSimilarity(aggregateGraphSymbol, sameKeyedSymbol)