use of org.eclipse.titan.designer.parsers.ProjectSourceParser in project titan.EclipsePlug-ins by eclipse.
the class ImportModule method checkImports.
@Override
public /**
* {@inheritDoc}
*/
void checkImports(final CompilationTimeStamp timestamp, final ModuleImportationChain referenceChain, final List<Module> moduleStack) {
if (lastImportCheckTimeStamp != null && !lastImportCheckTimeStamp.isLess(timestamp)) {
return;
}
final ProjectSourceParser parser = GlobalParser.getProjectSourceParser(project);
if (parser == null || identifier == null) {
lastImportCheckTimeStamp = timestamp;
referredModule = null;
return;
}
final Module temp = referredModule;
referredModule = parser.getModuleByName(identifier.getName());
if (temp != referredModule) {
setUnhandledChange(true);
}
if (referredModule == null) {
identifier.getLocation().reportSemanticError(MessageFormat.format(MISSINGMODULE, identifier.getDisplayName()));
lastImportCheckTimeStamp = timestamp;
return;
}
moduleStack.add(referredModule);
if (referenceChain.add(this)) {
if (hasImportOfImport) {
if (referredModule instanceof TTCN3Module) {
final TTCN3Module ttcnmodule = (TTCN3Module) referredModule;
final List<ImportModule> imports = ttcnmodule.getImports();
for (final ImportModule importation : imports) {
referenceChain.markState();
importation.checkImports(timestamp, referenceChain, moduleStack);
referenceChain.previousState();
}
} else {
// FIXME There was no test for this case
location.reportSemanticError("import of imports can only be used on TTCN-3 modules");
}
}
if (hasNormalImport) {
// TODO: Check, this is not recursive!!!!
referredModule.checkImports(timestamp, referenceChain, moduleStack);
}
}
moduleStack.remove(moduleStack.size() - 1);
// timestamp can be set only here to handle circular import chains!
lastImportCheckTimeStamp = timestamp;
}
use of org.eclipse.titan.designer.parsers.ProjectSourceParser in project titan.EclipsePlug-ins by eclipse.
the class Analyzer method analyzeProject.
/**
* Analyze a whole project.
* <p>
* Executes the configured code smell spotters on the given project. Locking
* the project to prevent modification of the AST is handled internally.
*
* @param monitor
* shows progress and makes it interruptable
* @param module
* the ttcn3 project to analyze
*
* @return the code smells found in the given project
*/
public MarkerHandler analyzeProject(final IProgressMonitor monitor, final IProject project) {
final ProjectSourceParser projectSourceParser = GlobalParser.getProjectSourceParser(project);
final Set<String> knownModuleNames = projectSourceParser.getKnownModuleNames();
final SubMonitor progress = SubMonitor.convert(monitor, 1 + knownModuleNames.size());
progress.subTask("Project level analysis");
final Map<IResource, List<Marker>> markers = new HashMap<IResource, List<Marker>>();
markers.put(project, internalAnalyzeProject(project));
progress.worked(1);
for (final String moduleName : knownModuleNames) {
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
final Module mod = projectSourceParser.getModuleByName(moduleName);
progress.subTask("Analyzing module " + mod.getName());
final IResource moduleResource = mod.getLocation().getFile();
markers.put(moduleResource, internalAnalyzeModule(mod));
progress.worked(1);
}
return new MarkerHandler(markers);
}
use of org.eclipse.titan.designer.parsers.ProjectSourceParser in project titan.EclipsePlug-ins by eclipse.
the class MetricData method measure.
/**
* Execute the metrics on the project and compose the results.
* <p>
* Note that internally the project is locked.
*
* @param project
* the project to analyze
*
* @return the composed result of the measurements
*/
public static MetricData measure(final IProject project) {
synchronized (project) {
// reading the lists of altsteps, testcases, functions and modules
// that are to be measured
final ProjectSourceParser parser = GlobalParser.getProjectSourceParser(project);
final Risks risks = new Risks();
final MutableMetricData data = new MutableMetricData(risks);
final List<Module> modules = new ArrayList<Module>();
final Map<Module, List<Def_Function>> functions = new HashMap<Module, List<Def_Function>>();
final Map<Module, List<Def_Testcase>> testcases = new HashMap<Module, List<Def_Testcase>>();
final Map<Module, List<Def_Altstep>> altsteps = new HashMap<Module, List<Def_Altstep>>();
for (final String modName : parser.getKnownModuleNames()) {
final Module module = parser.getModuleByName(modName);
modules.add(module);
}
for (final Module module : modules) {
final List<Def_Function> funs = new ArrayList<Def_Function>();
final List<Def_Testcase> tcs = new ArrayList<Def_Testcase>();
final List<Def_Altstep> als = new ArrayList<Def_Altstep>();
module.accept(new DefinitionCollector(funs, tcs, als));
functions.put(module, funs);
testcases.put(module, tcs);
altsteps.put(module, als);
}
data.modules = Collections.unmodifiableList(modules);
data.functions = Collections.unmodifiableMap(functions);
data.testcases = Collections.unmodifiableMap(testcases);
data.altsteps = Collections.unmodifiableMap(altsteps);
MetricData immutableData = new MetricData(project, data);
// initiate the metrics
final Metrics metrics = new Metrics();
for (final AltstepMetric am : AltstepMetric.values()) {
metrics.get(am).init(immutableData);
}
for (final FunctionMetric fm : FunctionMetric.values()) {
metrics.get(fm).init(immutableData);
}
for (final TestcaseMetric tm : TestcaseMetric.values()) {
metrics.get(tm).init(immutableData);
}
for (final ModuleMetric mm : ModuleMetric.values()) {
metrics.get(mm).init(immutableData);
}
for (final ProjectMetric pm : ProjectMetric.values()) {
metrics.get(pm).init(immutableData);
}
// altstep metrics and statistics
for (final AltstepMetric am : AltstepMetric.values()) {
final Statistics projectStats = measureEntities(data.altsteps, metrics.get(am), immutableData, data.altstepMetrics, data.altstepModuleStats);
data.altstepProjectStats.put(am, projectStats);
immutableData = new MetricData(project, data);
}
// function metrics and statistics
for (final FunctionMetric fm : FunctionMetric.values()) {
final Statistics projectStats = measureEntities(data.functions, metrics.get(fm), immutableData, data.functionMetrics, data.functionModuleStats);
data.functionProjectStats.put(fm, projectStats);
immutableData = new MetricData(project, data);
}
// testcase metrics and statistics
for (final TestcaseMetric tm : TestcaseMetric.values()) {
final Statistics projectStats = measureEntities(data.testcases, metrics.get(tm), immutableData, data.testcaseMetrics, data.testcaseModuleStats);
data.testcaseProjectStats.put(tm, projectStats);
immutableData = new MetricData(project, data);
}
// module metrics and statistics
for (final ModuleMetric mm : ModuleMetric.values()) {
final Map<Module, Number> metricResults = new HashMap<Module, Number>();
final int numberOfModules = data.modules.size();
double[] projectLevelResults = new double[numberOfModules];
int projectLevelCounter = 0;
for (final Module module : data.modules) {
final Number result = metrics.get(mm).measure(immutableData, module);
projectLevelResults[projectLevelCounter++] = result.doubleValue();
metricResults.put(module, result);
}
data.moduleMetrics.put(mm, metricResults);
data.moduleProjectStats.put(mm, new Statistics(projectLevelResults, mm, risks.getRisk(mm)));
}
// project metrics
for (final ProjectMetric pm : ProjectMetric.values()) {
final Number result = metrics.get(pm).measure(immutableData, project);
data.projectMetrics.put(pm, result);
}
return immutableData;
}
}
use of org.eclipse.titan.designer.parsers.ProjectSourceParser in project titan.EclipsePlug-ins by eclipse.
the class ImportSelectionDialog method organizeImportsEdit.
/**
* Organize the imports according to the global preferences. If set,
* <ul>
* <li>Add imports necessary for missing references,</li>
* <li>Remove unused imports,</li>
* <li>Sort the import statements.</li>
* </ul>
* <p>
* These changes are not applied in the function, just collected in a
* <link>MultiTextEdit</link>, which is then returned.
* </p>
* TODO: notice and handle ambiguous references
*
* @param module
* The module which import statements are to organize.
* @param document
* The document that contains the module.
*
* @return The edit, which contains the proper changes.
*/
private static MultiTextEdit organizeImportsEdit(final TTCN3Module module, final IDocument document) throws BadLocationException {
final IProject prj = module.getProject();
final String doc = document.get();
final MultiTextEdit insertEdit = new MultiTextEdit();
final MultiTextEdit removeEdit = new MultiTextEdit();
final List<ImportText> newImports = new ArrayList<ImportText>();
final List<ImportText> importsKept = new ArrayList<ImportText>();
boolean needSorting = false;
if (addImports) {
// register the new needed imports
final Set<String> importNamesAdded = new HashSet<String>();
for (final Reference ref : module.getMissingReferences()) {
final Location missLoc = findReferenceInProject(ref, prj);
if (missLoc != null) {
final IFile file = (IFile) missLoc.getFile();
final ProjectSourceParser parser = GlobalParser.getProjectSourceParser(file.getProject());
final Module addMod = parser.containedModule(file);
final String importName = addMod.getIdentifier().getTtcnName();
if (!importNamesAdded.contains(importName)) {
final StringBuilder impText = new StringBuilder("import from ").append(importName).append(" all;");
if (importChangeMethod.equals(OrganizeImportPreferencePage.COMMENT_THEM)) {
impText.append(" // Added automatically to resolve ").append(ref.getDisplayName());
}
newImports.add(new ImportText(importName, impText.toString() + NEWLINE));
importNamesAdded.add(importName);
if (reportDebug) {
final StringBuilder sb = new StringBuilder("For ").append(ref.getDisplayName()).append(": ");
sb.append(impText.toString());
TITANDebugConsole.println(sb.toString());
}
}
}
}
if (sortImports && !newImports.isEmpty()) {
needSorting = true;
}
}
if (!needSorting && sortImports) {
// are the imports already sorted ?
final List<ImportModule> oldImports = module.getImports();
for (int size = oldImports.size(), i = 0; i < size - 1 && !needSorting; i++) {
if (oldImports.get(i).getName().compareTo(oldImports.get(i + 1).getName()) > 0) {
needSorting = true;
}
if (oldImports.get(i).getLocation().getOffset() > oldImports.get(i + 1).getLocation().getOffset()) {
needSorting = true;
}
}
if (!needSorting && oldImports.size() > 1) {
// are the import strictly before the definitions ?
final int lastImportOffset = oldImports.get(oldImports.size() - 1).getLocation().getOffset();
final Definitions defs = module.getAssignmentsScope();
if (defs.getNofAssignments() > 0 && !oldImports.isEmpty()) {
for (int i = 0, size = defs.getNofAssignments(); i < size; ++i) {
final int temp = defs.getAssignmentByIndex(i).getLocation().getOffset();
if (temp < lastImportOffset) {
needSorting = true;
}
}
}
}
}
if (needSorting || removeImports) {
// remove the imports not needed, or every if sorting is required
for (final ImportModule m : module.getImports()) {
final Location delImp = m.getLocation();
final IRegion startLineRegion = document.getLineInformationOfOffset(delImp.getOffset());
final IRegion endLineRegion = document.getLineInformationOfOffset(delImp.getEndOffset());
final String delimeter = document.getLineDelimiter(document.getLineOfOffset(delImp.getEndOffset()));
final int delLength = delimeter == null ? 0 : delimeter.length();
if (needSorting || (removeImports && !m.getUsedForImportation())) {
if (reportDebug) {
final MessageConsoleStream stream = TITANDebugConsole.getConsole().newMessageStream();
TITANDebugConsole.println("Removing " + "'" + doc.substring(startLineRegion.getOffset(), endLineRegion.getOffset() + endLineRegion.getLength() + delLength) + "'", stream);
TITANDebugConsole.println("From " + startLineRegion.getOffset() + " till " + ((endLineRegion.getOffset() - startLineRegion.getOffset()) + endLineRegion.getLength() + delLength), stream);
}
if (importChangeMethod.equals(OrganizeImportPreferencePage.COMMENT_THEM)) {
removeEdit.addChild(new InsertEdit(m.getLocation().getOffset(), "/*"));
// hack to handle the semicolon
removeEdit.addChild(new InsertEdit(m.getLocation().getEndOffset() + 1, "*/"));
} else {
removeEdit.addChild(new DeleteEdit(startLineRegion.getOffset(), (endLineRegion.getOffset() - startLineRegion.getOffset()) + endLineRegion.getLength() + delLength));
}
}
if (needSorting && (!removeImports || m.getUsedForImportation())) {
importsKept.add(new ImportText(m.getName(), doc.substring(startLineRegion.getOffset(), endLineRegion.getOffset() + endLineRegion.getLength() + delLength)));
}
}
}
if (!newImports.isEmpty() || (sortImports && needSorting)) {
// always insert at the beginning of the file
final int line = document.getLineOfOffset(module.getAssignmentsScope().getLocation().getOffset());
final IRegion lineRegion = document.getLineInformation(line);
final String delimeter = document.getLineDelimiter(line);
final int delimeterLength = delimeter == null ? 0 : delimeter.length();
final int startPos = lineRegion.getOffset() + lineRegion.getLength() + delimeterLength;
if (sortImports) {
if (needSorting || !newImports.isEmpty()) {
final List<ImportText> results = new ArrayList<ImportText>();
results.addAll(importsKept);
results.addAll(newImports);
Collections.sort(results);
for (final ImportText i : results) {
insertEdit.addChild(new InsertEdit(startPos, i.getText()));
}
}
} else {
Collections.sort(newImports);
for (final ImportText i : newImports) {
insertEdit.addChild(new InsertEdit(startPos, i.getText()));
}
}
}
final MultiTextEdit resultEdit = new MultiTextEdit();
resultEdit.addChild(insertEdit);
resultEdit.addChild(removeEdit);
return resultEdit;
}
use of org.eclipse.titan.designer.parsers.ProjectSourceParser in project titan.EclipsePlug-ins by eclipse.
the class ImportSelectionDialog method organizeImportsChange.
/**
* Organize the import statements of a file. The necessary changes are
* collected and returned in a <code>TextFileChange</code> object.
*
* @param file
* The file to organize.
* @return The change to perform.
* @throws CoreException
* when document associated with the file can't be acquired.
*/
public static TextFileChange organizeImportsChange(final IFile file) throws CoreException {
sortImports = Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, PreferenceConstants.ORG_IMPORT_SORT, true, null);
addImports = Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, PreferenceConstants.ORG_IMPORT_ADD, true, null);
removeImports = Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, PreferenceConstants.ORG_IMPORT_REMOVE, true, null);
importChangeMethod = Platform.getPreferencesService().getString(Activator.PLUGIN_ID, PreferenceConstants.ORG_IMPORT_METHOD, OrganizeImportPreferencePage.JUST_CHANGE, null);
final String designerId = ProductConstants.PRODUCT_ID_DESIGNER;
final String displayDebugInfo = org.eclipse.titan.designer.preferences.PreferenceConstants.DISPLAYDEBUGINFORMATION;
reportDebug = Platform.getPreferencesService().getBoolean(designerId, displayDebugInfo, false, null);
final TextFileChange change = new TextFileChange(file.getName(), file);
final ProjectSourceParser projectSourceParser = GlobalParser.getProjectSourceParser(file.getProject());
final Module actualModule = projectSourceParser.containedModule(file);
if (!(actualModule instanceof TTCN3Module)) {
ErrorReporter.logError("The module is not a TTCN-3 module");
return change;
}
final TTCN3Module module = (TTCN3Module) actualModule;
final IDocument doc = change.getCurrentDocument(null);
try {
change.setEdit(organizeImportsEdit(module, doc));
} catch (BadLocationException e) {
ErrorReporter.logExceptionStackTrace("Error while organizing imports", e);
}
return change;
}
Aggregations