Commit 37e3e41e authored by Philip Makedonski's avatar Philip Makedonski
Browse files

* usage analyzer refinements

parent be0a2183
Loading
Loading
Loading
Loading
+0 −25
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
        <listEntry value="/de.ugoe.cs.swe.T3Q/src/de/ugoe/cs/swe/T3Q/T3Q.java"/>
    </listAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
        <listEntry value="1"/>
    </listAttribute>
    <stringAttribute key="org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE" value="${workspace_loc:/de.ugoe.cs.swe.T3Q/config}/XtextStandalone.log"/>
    <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
        <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
        <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
    </listAttribute>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.ugoe.cs.swe.T3Q.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="de.ugoe.cs.swe.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--config config/t3q.cfg --profile defaultProfile"/>
    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="de.ugoe.cs.swe.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms256m -Xmx4g"/>
    <stringAttribute key="yk-options" value="&#13;&#10;additional-options2=onexit\=snapshot&#13;&#10;"/>
</launchConfiguration>

de.ugoe.cs.swe.T3Q/T3Q.launch

deleted100644 → 0
+0 −25
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
        <listEntry value="/de.ugoe.cs.swe.T3Q/src/de/ugoe/cs/swe/T3Q/T3Q.java"/>
    </listAttribute>
    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
        <listEntry value="1"/>
    </listAttribute>
    <stringAttribute key="org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE" value="${workspace_loc:/de.ugoe.cs.swe.T3Q/config}/XtextStandalone.log"/>
    <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
        <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
        <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
    </listAttribute>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.ugoe.cs.swe.T3Q.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="de.ugoe.cs.swe.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--config config/t3q.cfg --profile defaultProfile"/>
    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="de.ugoe.cs.swe.T3Q"/>
    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms256m -Xmx4g"/>
    <stringAttribute key="yk-options" value="&#13;&#10;additional-options2=onexit\=snapshot&#13;&#10;"/>
</launchConfiguration>
+113 −29
Original line number Diff line number Diff line
package de.ugoe.cs.swe.T3Q;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.grammaranalysis.impl.GrammarElementTitleSwitch;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.impl.InternalNodeModelUtils;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;

import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import de.ugoe.cs.swe.common.MiscTools;
import de.ugoe.cs.swe.common.logging.LoggingInterface;
import de.ugoe.cs.swe.services.TTCN3GrammarAccess;
import de.ugoe.cs.swe.tTCN3.AltConstruct;
import de.ugoe.cs.swe.tTCN3.FunctionDef;
import de.ugoe.cs.swe.tTCN3.ModuleDefinition;
import de.ugoe.cs.swe.tTCN3.TTCN3File;
import de.ugoe.cs.swe.tTCN3.TTCN3Module;
import de.ugoe.cs.swe.tTCN3.TTCN3Package;
import de.ugoe.cs.swe.tTCN3.Type;
import de.ugoe.cs.swe.tTCN3.impl.TTCN3PackageImpl;

public class UsageAnalyzer implements Callable<TTCN3Usage> {
	private final Resource resource;
@@ -41,37 +60,102 @@ public class UsageAnalyzer implements Callable<TTCN3Usage> {
		EcoreUtil.resolveAll(this.resource);
		//get root element
		EObject model = this.resource.getContents().get(0);
		//collect basic stats (keep in mind multi-threaded processing, need to collect output in a file or in output), 
		//for initial basic testing single-threaded mode should provide first results
		System.out.println("Module,FunctionDef,AltConstruct,...");
		for (TTCN3Module module : ((TTCN3File)model).getModules()) {
			//immediate output (will look weird if single-core is not activated)
			//TODO: count different constructs (naive approach), e.g.
			System.out.println(module.getName() 
					+ "," +EcoreUtil2.getAllContentsOfType(module, FunctionDef.class).size()
					+ "," +EcoreUtil2.getAllContentsOfType(module, AltConstruct.class).size()
					+ ",..." 
					);
			//TODO: very inefficient, better to traverse tree once, e.g.
			List<ModuleDefinition> definitions = EcoreUtil2.getAllContentsOfType(module, ModuleDefinition.class);

			//process with a stream
			Map<String, List<ModuleDefinition>> groupedDefinitions = definitions.stream()
					.collect(Collectors.groupingBy(e->e.getDef().eClass().getName()));
			//immediate output (will look weird if single-core is not activated)
			//groupedDefinitions.forEach((k,v) -> System.out.println(k+","+v.size()));
			//collect for synchronised output
			output.getOutput().putAll(groupedDefinitions.entrySet().stream()
					.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().size())));
			//or
			//groupedDefinitions.forEach((k,v) -> output.getOutput().put(k, v.size()));
			
			//...or with a loop
			for (ModuleDefinition d : definitions) {
				String eClassName = d.getDef().eClass().getName();
				//...
		
		//--------------------------------------------------------
		//TODO: per file, total

		//These should be all the e-classes available -> init / compare with collected
		//TODO: add to dependencies explicitly!!!
		//dump all
//		TTCN3Package.eINSTANCE.eContents().forEach(e -> System.out.println(((org.eclipse.emf.ecore.ENamedElement)e).getName()));
		
		//initialise all with 0
		Map<String, Long> counts = TTCN3Package.eINSTANCE.eContents()
			.stream().map(e -> ((ENamedElement)e).getName())
			.collect(Collectors.toMap(e->e, v->0L))
			;
		
		
		//sample generic collector (could probably be improved further but it gets the job done)
		ArrayList<EObject> nodes = Lists.newArrayList(model.eAllContents());
		
		//group and count encountered
		Map<String, Long> grouped = nodes.stream()
				.collect(Collectors
						.groupingBy(e->e.eClass().getName(), Collectors.counting()));
		
		//integrate into all
		grouped.forEach((k,v) -> counts.put(k, v));
		
		//Non-class elements
		List<Type> typeSpecs = EcoreUtil2.eAllOfType(model, Type.class);
		System.out.println(typeSpecs);
		
		GrammarElementTitleSwitch grammarElementHandler = new GrammarElementTitleSwitch();
		ICompositeNode root = NodeModelUtils.findActualNodeFor(model);
//		System.out.println(NodeModelUtils.compactDump(root, false));
		root.getAsTreeIterable().forEach(node -> {
			if (node instanceof ILeafNode && ((ILeafNode) node).isHidden()) {
				
			} else {
				//DONE: show leaves only? -> not very useful (only terminals)
				String element = grammarElementHandler.doSwitch(node.getGrammarElement());
				System.out.println(element);
			}
		}
		);
		
		nodes.forEach(node -> {
//			System.out.println(node.eClass().getName());
		});
		
		//dump sorted
//		counts.entrySet().stream()
//			.sorted(Comparator.comparing(Entry::getKey))
//			.forEach(e -> System.out.println(e.getKey()+" : "+e.getValue()))
//			;

		//create basic json
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
		String json = gson.toJson(counts);
//		System.out.println(json);
		//TODO: store as file? or return and integrate?
		
		//--------------------------------------------------------

		
		//collect basic stats (keep in mind multi-threaded processing, need to collect output in a file or in output), 
		//for initial basic testing single-threaded mode should provide first results
//		System.out.println("Module,FunctionDef,AltConstruct,...");
//				
//		for (TTCN3Module module : ((TTCN3File)model).getModules()) {
//			//immediate output (will look weird if single-core is not activated)
//			//TODO: count different constructs (naive approach), e.g.
//			System.out.println(module.getName() 
//					+ "," +EcoreUtil2.getAllContentsOfType(module, FunctionDef.class).size()
//					+ "," +EcoreUtil2.getAllContentsOfType(module, AltConstruct.class).size()
//					+ ",..." 
//					);
//			//TODO: very inefficient, better to traverse tree once, e.g.
//			List<ModuleDefinition> definitions = EcoreUtil2.getAllContentsOfType(module, ModuleDefinition.class);
//
//			//process with a stream
//			Map<String, List<ModuleDefinition>> groupedDefinitions = definitions.stream()
//					.collect(Collectors.groupingBy(e->e.getDef().eClass().getName()));
//			//immediate output (will look weird if single-core is not activated)
//			//groupedDefinitions.forEach((k,v) -> System.out.println(k+","+v.size()));
//			//collect for synchronised output
//			output.getOutput().putAll(groupedDefinitions.entrySet().stream()
//					.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().size())));
//			//or
//			//groupedDefinitions.forEach((k,v) -> output.getOutput().put(k, v.size()));
//			
//			//...or with a loop
//			for (ModuleDefinition d : definitions) {
//				String eClassName = d.getDef().eClass().getName();
//				//...
//			}
//		}

		stopwatch.stop();