Skip to content
donat edited this page Sep 4, 2012 · 12 revisions

This page summarizes what queries should be implemented upon the models using IncQuery.

We have 2 models:

  • A big, emf model which comes the databases. It contains the structure of the committed projects in a central release repository. The stored dependencies are only inter-project, not inter-project ones.
  • A small workspace model which describes the structure of the loaded projects in the workspace.

To make the big model fit into the relatively small memory, we should create smaller, more compact model from the server model by leaving out certain information.

Queries

JOIN Find the related elements in the two models. Check that every (unmodified) element has a correspondent pair in the big database.

package cern.devtools.deps.query

import "http://inf.mit.bme.hu/donat/incquery-deps/wsmodel"
import "http://inf.mit.bme.hu/donat/incquery-deps/repomodel"

pattern joinProject(rp : RProject, wp : WProject) = {
    RProject.name(rp, commonName);
    WProject.name(wp, commonName);
}

pattern joinClass(rc : RClass, wc : WType) = {
    // Join project.
    RProject.rClasses(rp, rc);
    WProject.packageFragmentRoots.packageFragments.compilationUnits.types(wp, wc);
    find joinProject(rp, wp);

    // Join class name.
    RClass.simpleName(rc, simplename);
    WType.name(wc, simplename);

    // Join class' package name.
    RClass.packageName(rc, packagename);
    WPackageFragment.compilationUnits.types(wpfg, wc);
    WPackageFragment.name(wpfg, packagename);
}

pattern joinMethod(rm : RMethod, wm : WMethod) = {
    // Join project.
    RProject.rClasses.rMethods(rp, rm);
    WProject.packageFragmentRoots.packageFragments.compilationUnits.types.methods(wp, wm);
    find joinProject(rp, wp);

    // Join classes.
    // There is no need for it: signature contains the fully qualified names.
    // RClass.rMethods(rc, rm);
    // WType.methods(wc, wm);
    // find joinClass(rc, wc);

    // join methods by signature
    RMethod.signature(rm, signature);
    WMethod.signature(wm, signature);
}

INCOMING After joining, the next step is to show, how many incoming dependencies does one item have. It can signal the developer, which are the significant methods which are not supposed to change.

pattern joinField(rm : RField, wm : WField) = {
	// Join project.
	RProject.rClasses.rFields(rp, rm);	
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types.fields(wp, wm);
	find joinProject(rp, wp);

	// Join classes.
	// There is no need for it: signature contains the fully qualified names.
	// RClass.rMethods(rc, rm);
	// WType.methods(wc, wm);
	// find joinClass(rc, wc);
	
	// join methods by signature
	RField.signature(rm, signature);
	WField.signature(wm, signature);
}


pattern incomingInheritanceDeps(from : RClass, to : RClass, wsTo : WType) = {
	// Find the correspondent items.
	find joinClass(to, wsTo);
	
	// Join on dependencies.
	RDependency.rFrom(d, from);
	RDependency.rTo(d, to);
	
	// Select only inheritance dependencies.
	RDependency.depType(d,5);
}

pattern incomingClassUsageDeps(from : RClass, to : RClass, wsTo : WType) = {
	find joinClass(to, wsTo);
	RDependency.rFrom(d, from);
	RDependency.rTo(d, to);
	RDependency.depType(d,4);
}

pattern incomingMethodCallDeps(from : RMethod , to : RMethod, wsTo : WMethod) = {
	find joinMethod(to, wsTo);
	RDependency.rFrom(d, from);
	RDependency.rTo(d, to);
	RDependency.depType(d,1);
}

pattern incomingMethodOverrideDeps(from : RMethod , to : RMethod, wsTo : WMethod) = {
	find joinMethod(to, wsTo);
	RDependency.rFrom(d, from);
	RDependency.rTo(d, to);
	RDependency.depType(d,2);
}

pattern incomingFieldAccessDeps(from : RMethod , to : RField, wsTo : WField) = {
	find joinField(to, wsTo);
	RDependency.rFrom(d, from);
	RDependency.rTo(d, to);
	RDependency.depType(d,3);
}

DELTA Find the modified elements. Classes/method/fields which are added to the workspace and not part of the big model or vica versa: when something is deleted from the workspace but it exists in the big model.

pattern addedClasses(c : WType) = {
	WPackageFragment.compilationUnits.types(p, c);
	WPackageFragment.name(p, packageName);
	WType.name(c, simpleName);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types(wp, c);
	// same project
	find joinProject(rp, wp);
	// but the class does not exist in the workspace
	neg find repoClassNameAndPackageName(rp, packageName, simpleName);
}

pattern removedClasses(c : RClass) = {
	RClass.simpleName(c, simpleName);
	RClass.packageName(c, packageName);
	RProject.rClasses(rp, c);

	// same project
	find joinProject(rp, wp);

	// but the workspace does not contain the class stored in the project
	neg find workspaceClassnameAndPackageName(wp, packageName, simpleName);
}

pattern addedMethods(c : WMethod) = {
	WMethod.signature(c, signature);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types.methods(p, c);

	//same project
	find joinProject(rp, p);
	neg find repoMethodSignatures(rp, signature);
}

pattern removedMethod(m : RMethod) = {
	RMethod.signature(m, signature);
	RProject.rClasses.rMethods(rp, m);
	
	find joinProject(rp, wp);
	neg find workspaceMethodSignatures(wp, signature);
	
	check (!signature.contains("<clinit>"));
}

pattern addedFields(f : WField) = {
	WField.signature(f, signature);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types.fields(p, f);

	//same project
	find joinProject(rp, p);
	neg find repoFieldSignatures(rp, signature);
}

pattern removedFields(f : RField) = {
	RField.signature(f, signature);
	RProject.rClasses.rFields(rp, f);
	
	find joinProject(rp, wp);
	neg find workspaceFieldSignatures(wp, signature);
}


pattern workspaceClassnameAndPackageName(wp, packageName, simpleName) = {
	WType(c);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types(wp, c);
	WPackageFragment.compilationUnits.types(p, c);
	WPackageFragment.name(p, packageName);
	WType.name(c, simpleName);
}

pattern repoClassNameAndPackageName(rp, packageName, simpleName) = {
	RProject.rClasses(rp, rc);
	RClass(rc);
	RClass.packageName(rc, packageName);
	RClass.simpleName(rc, simpleName);
}

pattern repoMethodSignatures(rp, signature) = {
	RProject(rp);
	RProject.rClasses.rMethods.signature(rp, signature);
}

pattern workspaceMethodSignatures(wp, signature) = {
	WProject(wp);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types.methods.signature(wp, signature);
}

pattern repoFieldSignatures(rp, signature) = {
	RProject(rp);
	RProject.rClasses.rFields.signature(rp, signature);
}

pattern workspaceFieldSignatures(wp, signature) = {
	WProject(wp);
	WProject.packageFragmentRoots.packageFragments.compilationUnits.types.fields.signature(wp, signature);
}

IMPACT If a workspace contains some changes, we want to know, how big an impact would be, if the changes are committed to the repository. The practical use-cases:

  • removed items: class, method, field: we would like to see all the incoming dependencies for these items.
  • change in inheritance tree: incoming dependency inheritance. (just an idea).

OUTGOING If a big database has a dependency, it should be present in the workspace model too. If there is a difference maybe a useful information. (This one requires the dependency discovery in the modelfinder plugin).

Clone this wiki locally