use of org.eclipse.titan.designer.AST.Module in project titan.EclipsePlug-ins by eclipse.
the class BrokenPartsViaReferences method collectRealBrokenParts.
protected void collectRealBrokenParts(final Map<Module, List<AssignmentHandler>> moduleAndAssignments, final boolean useIncrementalParsing) {
for (Map.Entry<Module, List<AssignmentHandler>> entry : moduleAndAssignments.entrySet()) {
final List<Assignment> assignments = new ArrayList<Assignment>();
for (AssignmentHandler assignmentHandler : entry.getValue()) {
if (!useIncrementalParsing || assignmentHandler.getIsInfected()) {
assignments.add(assignmentHandler.getAssignment());
}
assignmentHandler.assignment.notCheckRoot();
}
final Module module = entry.getKey();
if (!assignments.isEmpty() || !module.getSkippedFromSemanticChecking()) {
moduleAndBrokenAssignments.put(module, assignments);
modulesToCheck.add(module);
}
}
}
use of org.eclipse.titan.designer.AST.Module in project titan.EclipsePlug-ins by eclipse.
the class BrokenPartsViaReferences method buildInvertedImportStructure.
/**
* It is build an inverted import structure and identify startmodules whose CompilationTimeStamp is null.
*
* @param allModules
* the list of modules to be check. Initially all modules.
* @param startModules
* the list of modules to be check. Initially all modules, but the function will remove those that can be skipped.
*
* @return invertedImports contains the next:<br>
* - key: a module.<br>
* - values: in these modules the key module is used, so all values imported this module, it is an inverted "imported" connection.<br>
* If module A import B, C, D and module B import D, E then the next structure will be built:<br>
* A = [],<br>
* B = [A],<br>
* C = [A],<br>
* D = [A, B],<br>
* E = [B]<br>
*/
protected Map<Module, List<Module>> buildInvertedImportStructure(final List<Module> allModules, final List<Module> startModules) {
final Map<Module, List<Module>> invertedImports = new HashMap<Module, List<Module>>();
for (Module actualModule : allModules) {
// It covers the case when a module is a top-level module, so it has't got any import.
if (!invertedImports.containsKey(actualModule)) {
invertedImports.put(actualModule, new ArrayList<Module>());
}
for (Module actualImportedModule : actualModule.getImportedModules()) {
if (invertedImports.containsKey(actualImportedModule)) {
final List<Module> dependentModules = invertedImports.get(actualImportedModule);
if (!dependentModules.contains(actualModule)) {
dependentModules.add(actualModule);
}
} else {
final List<Module> temp = new ArrayList<Module>();
temp.add(actualModule);
invertedImports.put(actualImportedModule, temp);
}
}
}
return invertedImports;
}
use of org.eclipse.titan.designer.AST.Module in project titan.EclipsePlug-ins by eclipse.
the class BrokenPartsViaReferences method processStartModules.
public void processStartModules(final List<Module> startModules, final Map<Module, List<AssignmentHandler>> moduleAndBrokenAssignments) {
for (Module startModule : startModules) {
if (isTooSlow()) {
return;
}
if (startModule instanceof TTCN3Module && startModule.getLastCompilationTimeStamp() != null && !startModule.isCheckRoot()) {
// definition name has not changed but module semantically has not been checked:
final Assignments startAssignments = startModule.getAssignments();
final List<AssignmentHandler> brokens = new ArrayList<AssignmentHandler>();
final List<AssignmentHandler> notBrokens = new ArrayList<AssignmentHandler>();
for (Assignment assignment : startAssignments) {
MarkerHandler.markAllSemanticMarkersForRemoval(assignment);
}
for (int d = 0; d < startAssignments.getNofAssignments(); ++d) {
final Assignment startAssignment = startAssignments.getAssignmentByIndex(d);
final AssignmentHandler assignmentHandler = AssignmentHandlerFactory.getDefinitionHandler(startAssignment);
startAssignment.check(timestamp);
startAssignment.accept(assignmentHandler);
if (startAssignment.isCheckRoot()) {
assignmentHandler.setIsInfected(true);
startAssignment.notCheckRoot();
assignmentHandler.addReason("Definition's infected, because of incremental parsing.");
brokens.add(assignmentHandler);
} else if (assignmentHandler.getIsInfected()) {
assignmentHandler.addReason("Definition contains an infected reference.");
brokens.add(assignmentHandler);
} else {
notBrokens.add(assignmentHandler);
}
}
if (!brokens.isEmpty()) {
checkLocalAssignments(brokens, notBrokens);
if (moduleAndBrokenAssignments.containsKey(startModule)) {
moduleAndBrokenAssignments.get(startModule).addAll(brokens);
} else {
moduleAndBrokenAssignments.put(startModule, brokens);
}
}
} else {
if (startModule.getLastCompilationTimeStamp() == null) {
// The markers have been marked for removal only for ASN1 modules
startModule.check(timestamp);
}
// puts additional markers!
final List<AssignmentHandler> startAssignments = getAssignmentsFrom(startModule);
for (AssignmentHandler assignmentHandler : startAssignments) {
assignmentHandler.initStartParts();
assignmentHandler.assignment.notCheckRoot();
assignmentHandler.addReason("Parent module's CompilationTimeStamp is null.");
}
if (moduleAndBrokenAssignments.containsKey(startModule)) {
moduleAndBrokenAssignments.get(startModule).addAll(startAssignments);
} else {
moduleAndBrokenAssignments.put(startModule, startAssignments);
}
}
startModule.notCheckRoot();
}
}
use of org.eclipse.titan.designer.AST.Module in project titan.EclipsePlug-ins by eclipse.
the class ImportSelectionDialog method findReferenceInProject.
/**
* Try to find the declaration of the reference in any module of the
* project.
* <p>
* If exactly one declaration is found, then its location is returned. If
* multiple modules contain a valid declaration of the reference, then a
* dialog is displayed to the user to choose one. If none found, or the user
* cancels the dialog, <code>null</code> is returned.
* </p>
*
* @param reference
* The (missing) reference we are searching for.
* @param project
* The project in which we search the declaration.
* @return The location of the declaration, if uniquely found,
* <code>null</code> otherwise.
*/
public static Location findReferenceInProject(final Reference reference, final IProject project) {
final ProjectSourceParser projectSourceParser = GlobalParser.getProjectSourceParser(project);
final List<DeclarationCollectionHelper> collected = new ArrayList<DeclarationCollectionHelper>();
final Identifier identifier = reference.getId();
for (final String moduleName : projectSourceParser.getKnownModuleNames()) {
final Module m = projectSourceParser.getModuleByName(moduleName);
if (m != null && m.getAssignments().hasLocalAssignmentWithID(CompilationTimeStamp.getBaseTimestamp(), identifier)) {
Assignment assignment = m.getAssignments().getLocalAssignmentByID(CompilationTimeStamp.getBaseTimestamp(), identifier);
if (assignment != null) {
collected.add(new DeclarationCollectionHelper(assignment.getProposalDescription(), assignment.getIdentifier().getLocation(), assignment));
}
}
}
Location loc = null;
if (collected.size() > 1) {
final List<String> files = new ArrayList<String>();
for (final DeclarationCollectionHelper c : collected) {
files.add(c.location.getFile().getName());
}
TITANDebugConsole.println("Multiple possible imports for " + reference.getDisplayName() + ": " + files.toString());
final ImportSelectionDialog dialog = new ImportSelectionDialog(reference, collected, reference.getLocation().getFile());
Display.getDefault().syncExec(dialog);
loc = dialog.getSelected();
} else if (collected.size() == 1) {
DeclarationCollectionHelper declaration = collected.get(0);
loc = declaration.location;
TITANDebugConsole.println("Exactly one module for " + reference.getDisplayName() + " is found: " + loc.getFile().getName());
} else {
TITANDebugConsole.println("No imports for " + reference.getDisplayName() + " is found");
}
return loc;
}
use of org.eclipse.titan.designer.AST.Module 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();
if (insertEdit.hasChildren()) {
resultEdit.addChild(insertEdit);
}
if (removeEdit.hasChildren()) {
resultEdit.addChild(removeEdit);
}
return resultEdit;
}
Aggregations