X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2FGraphCompiler.java;fp=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2FGraphCompiler.java;h=21761a3b156d2e404684a830745a33a5a9c043ad;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphCompiler.java b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphCompiler.java new file mode 100644 index 000000000..21761a3b1 --- /dev/null +++ b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphCompiler.java @@ -0,0 +1,266 @@ +package org.simantics.graph.compiler; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Formatter; +import java.util.Locale; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Files; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.container.DataContainer; +import org.simantics.databoard.container.DataContainers; +import org.simantics.databoard.serialization.SerializationException; +import org.simantics.graph.compiler.internal.parsing.Parsing; +import org.simantics.graph.compiler.internal.procedures.AddConsistsOf; +import org.simantics.graph.compiler.internal.procedures.ApplyTemplates; +import org.simantics.graph.compiler.internal.procedures.Compactify; +import org.simantics.graph.compiler.internal.procedures.ConvertPreValues; +import org.simantics.graph.compiler.internal.procedures.CreateInverseRelations; +import org.simantics.graph.compiler.internal.procedures.CreateTemplates; +import org.simantics.graph.compiler.internal.procedures.DefaultValueTyping; +import org.simantics.graph.compiler.internal.procedures.MergeEqualResources; +import org.simantics.graph.compiler.internal.procedures.PropagateNewMarks; +import org.simantics.graph.compiler.internal.resourceFiles.ResourceFileGenerator; +import org.simantics.graph.compiler.internal.store.LocationStore; +import org.simantics.graph.compiler.internal.store.VariableStore; +import org.simantics.graph.compiler.internal.validation.ReportCollisions; +import org.simantics.graph.compiler.internal.validation.ValidateGraph; +import org.simantics.graph.query.CompositeGraph; +import org.simantics.graph.query.Paths; +import org.simantics.graph.query.TransferableGraphConversion; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.graph.store.GraphStore; +import org.simantics.ltk.FileSource; +import org.simantics.ltk.ISource; +import org.simantics.ltk.Location; +import org.simantics.ltk.Problem; + +public class GraphCompiler { + + public static PrintStream out = System.out; + + public static TransferableGraph1 read(File file) throws Exception { + DataContainer container = DataContainers.readFile(file); + return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING); + } + + public static TransferableGraph1 read(InputStream stream) throws AdaptException, IOException { + DataContainer container = DataContainers.readFile(new DataInputStream(stream)); + stream.close(); + return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING); + } + + public static InputStream write(TransferableGraph1 tg) throws BindingException, IOException { + byte[] buffer = DataContainers.writeFile( + new DataContainer("graph", 1, new Variant(TransferableGraph1.BINDING, tg)) + ); + return new ByteArrayInputStream(buffer); + } + + public static CompilationResult compile( + String Layer0Version, + Collection sources, + Collection dependencies, + ExternalFileLoader fileLoader, + GraphCompilerPreferences preferences) { + out.println(preferences); + + Collection errors = new ArrayList(); + GraphStore store = new GraphStore(); + + CompilationResult compilationResult = new CompilationResult(); + compilationResult.errors = errors; + compilationResult.warnings = new ArrayList(); + + Paths paths = new Paths(Layer0Version); + + try { + run(new Parsing(paths, sources, errors, store)); + + if(!errors.isEmpty()) + return compilationResult; + + // Create composite graph of the new statements and dependencies + CompositeGraph graph; + { + long beginTime = System.nanoTime(); + graph = TransferableGraphConversion.convert(paths, dependencies); + graph.addFragment(store); + long endTime = System.nanoTime(); + reportTime("Composition", beginTime, endTime); + } + + // Procedures + run(new MergeEqualResources(paths, store)); + { + int[] unfoundedIdentitities = store.identities.getUnfoundedIdentities(); + if(unfoundedIdentitities.length > 0) { + LocationStore locations = store.getStore(LocationStore.class); + for(int id : unfoundedIdentitities) { + errors.add(new Problem( + locations.getLocation(id), + "URIless resource used as a parent.")); + } + return compilationResult; + } + } + store.identities.createPathToId(paths.ConsistsOf); + run(new CreateTemplates(graph, store, errors)); + run(new ApplyTemplates(graph, store, errors, fileLoader)); + run(new DefaultValueTyping(paths, store)); + run(new Compactify(store)); + run(new PropagateNewMarks(store)); + run(new CreateInverseRelations(graph, store)); + run(new AddConsistsOf(paths, store)); + run(new ConvertPreValues(graph, store, errors)); + run(new ReportCollisions(errors, store)); + if(preferences.validate) + run(new ValidateGraph(graph, errors, store, preferences)); + + // Create the result + { + long beginTime = System.nanoTime(); + compilationResult.graph = TransferableGraphConversion.convert(graph, store); + long endTime = System.nanoTime(); + reportTime("Generate TG", beginTime, endTime); + } + + // Create resource files + { + long beginTime = System.nanoTime(); + compilationResult.resourceFiles = ResourceFileGenerator.generate(paths, store); + long endTime = System.nanoTime(); + reportTime("Generate resources", beginTime, endTime); + } + + // Create source info + { + VariableStore variableStore = store.getStore(VariableStore.class); + compilationResult.sourceInfo = variableStore.getSourceInfo(); + } + + // Fix source location of problems whose location is null at this point + + for(Problem problem : compilationResult.errors) { + if(problem.getLocation() == null) + for(ISource source : sources) { + problem.setLocation(new Location(source)); + break; + } + else if(problem.getLocation().getSource() == null) + for(ISource source : sources) { + problem.getLocation().setSource(source); + break; + } + } + for(Problem problem : compilationResult.warnings) { + if(problem.getLocation() == null) + for(ISource source : sources) { + problem.setLocation(new Location(source)); + break; + } + else if(problem.getLocation().getSource() == null) + for(ISource source : sources) { + problem.getLocation().setSource(source); + break; + } + } + + } catch(Exception e) { + e.printStackTrace(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + e.printStackTrace(new PrintStream(stream)); + String description = "Internal error: " + + new String(stream.toByteArray()); + for(ISource source : sources) + errors.add(new Problem(new Location(source), description)); + } + + return compilationResult; + } + + private static void run(Runnable runnable) { + long beginTime = System.nanoTime(); + runnable.run(); + long endTime = System.nanoTime(); + + reportTime(runnable.getClass().getSimpleName(), beginTime, endTime); + } + + public static void reportTime(String taskName, long beginTime, long endTime) { + StringBuilder sb = new StringBuilder(); + Formatter formatter = new Formatter(sb, Locale.US); + formatter.format("%-25s %8.4f ms", taskName, (endTime - beginTime)*1e-6); + + out.println(sb.toString()); + } + + public static void reportTime(String taskName, long beginTime) { + reportTime(taskName, beginTime, System.nanoTime()); + } + + public static void main(String[] args) { + Collection sources = new ArrayList(); + Collection dependencies = new ArrayList(); + String outputFile = null; + + for(int i=0;i