Search in sources :

Example 11 with ImportModule

use of org.eclipse.titan.designer.AST.TTCN3.definitions.ImportModule in project titan.EclipsePlug-ins by eclipse.

the class TTCN3Module method analyzeExtensionAttributes.

/**
 * Convert and check the version, requires and titan version extension attributes.
 *
 * @param timestamp
 *                the timestamp of the actual build cycle.
 */
private void analyzeExtensionAttributes(final CompilationTimeStamp timestamp) {
    if (withAttributesPath == null) {
        return;
    }
    final List<SingleWithAttribute> realAttributes = withAttributesPath.getRealAttributes(timestamp);
    SingleWithAttribute attribute;
    List<AttributeSpecification> specifications = null;
    for (int i = 0; i < realAttributes.size(); i++) {
        attribute = realAttributes.get(i);
        if (Attribute_Type.Extension_Attribute.equals(attribute.getAttributeType())) {
            final Qualifiers qualifiers = attribute.getQualifiers();
            if (qualifiers == null || qualifiers.getNofQualifiers() == 0) {
                if (specifications == null) {
                    specifications = new ArrayList<AttributeSpecification>();
                }
                specifications.add(attribute.getAttributeSpecification());
            }
        }
    }
    if (specifications == null) {
        return;
    }
    final List<ExtensionAttribute> attributes = new ArrayList<ExtensionAttribute>();
    AttributeSpecification specification;
    for (int i = 0; i < specifications.size(); i++) {
        specification = specifications.get(i);
        final ExtensionAttributeAnalyzer analyzer = new ExtensionAttributeAnalyzer();
        analyzer.parse(specification);
        final List<ExtensionAttribute> temp = analyzer.getAttributes();
        if (temp != null) {
            attributes.addAll(temp);
        }
    }
    ExtensionAttribute extensionAttribute;
    for (int i = 0; i < attributes.size(); i++) {
        extensionAttribute = attributes.get(i);
        switch(extensionAttribute.getAttributeType()) {
            case VERSION:
                {
                    final ModuleVersionAttribute moduleVersion = (ModuleVersionAttribute) extensionAttribute;
                    moduleVersion.parse();
                    if (versionNumber != null) {
                        moduleVersion.getLocation().reportSemanticError("Duplicate version attribute");
                    } else {
                        setVersion(moduleVersion.getVersionNumber());
                    }
                    break;
                }
            case REQUIRES:
                {
                    final VersionRequirementAttribute versionReq = (VersionRequirementAttribute) extensionAttribute;
                    versionReq.parse();
                    ImportModule theImport = null;
                    final String requiredModuleName = versionReq.getRequiredModule().getName();
                    for (final ImportModule impMod : importedModules) {
                        if (requiredModuleName.equals(impMod.getIdentifier().getName())) {
                            theImport = impMod;
                            break;
                        }
                    }
                    if (theImport == null) {
                        final String message = MessageFormat.format(ImportModule.MISSINGMODULE, versionReq.getRequiredModule().getDisplayName());
                        versionReq.getRequiredModule().getLocation().reportSemanticError(message);
                    } else {
                        final TTCN3Module theImportedModule = (TTCN3Module) theImport.getReferredModule();
                        // make sure the version attribute is parsed (if any)
                        theImportedModule.check(timestamp);
                        final ProductIdentity requiredVersion = versionReq.getVersionNumber();
                        if (requiredVersion != null && theImportedModule.versionNumber != null && theImportedModule.versionNumber.compareTo(requiredVersion) < 0) {
                            final String message = MessageFormat.format("Module `{0}'' requires version {1} of module `{2}'', but only version {3} is available", identifier.getDisplayName(), requiredVersion.toString(), theImportedModule.getIdentifier().getDisplayName(), theImportedModule.versionNumber.toString());
                            versionReq.getLocation().reportSemanticError(message);
                        }
                    }
                    break;
                }
            case TITANVERSION:
                {
                    final TitanVersionAttribute titanReq = (TitanVersionAttribute) extensionAttribute;
                    titanReq.parse();
                    final ProductIdentity requiredTITANVersion = titanReq.getVersionNumber();
                    final String temp = CompilerVersionInformationCollector.getCompilerProductNumber();
                    final ProductIdentity compilerVersion = ProductIdentityHelper.getProductIdentity(temp, null);
                    if (requiredTITANVersion != null && compilerVersion != null && compilerVersion.compareTo(requiredTITANVersion) < 0) {
                        final String message = MessageFormat.format("Module `{0}'' requires TITAN version {1}, but version {2} is used right now", identifier.getDisplayName(), requiredTITANVersion.toString(), compilerVersion.toString());
                        titanReq.getLocation().reportSemanticError(message);
                    }
                    if (requiredTITANVersion != null && GeneralConstants.ON_THE_FLY_ANALYZER_VERSION != null && GeneralConstants.ON_THE_FLY_ANALYZER_VERSION.compareTo(requiredTITANVersion) < 0) {
                        final String message = MessageFormat.format("Module `{0}'' requires TITAN version {1}, but the on-the-fly analyzer is of version {2}", identifier.getDisplayName(), requiredTITANVersion.toString(), GeneralConstants.ON_THE_FLY_ANALYZER_VERSION.toString());
                        titanReq.getLocation().reportSemanticError(message);
                    }
                    break;
                }
            default:
                // we don't care
                break;
        }
    }
}
Also used : ModuleVersionAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.ModuleVersionAttribute) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) SingleWithAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute) ExtensionAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.ExtensionAttribute) AttributeSpecification(org.eclipse.titan.designer.AST.TTCN3.attributes.AttributeSpecification) VersionRequirementAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.VersionRequirementAttribute) ProductIdentity(org.eclipse.titan.common.product.ProductIdentity) ExtensionAttributeAnalyzer(org.eclipse.titan.designer.parsers.extensionattributeparser.ExtensionAttributeAnalyzer) TitanVersionAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.TitanVersionAttribute) Qualifiers(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers)

Example 12 with ImportModule

use of org.eclipse.titan.designer.AST.TTCN3.definitions.ImportModule 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;
}
Also used : InsertEdit(org.eclipse.text.edits.InsertEdit) IFile(org.eclipse.core.resources.IFile) Reference(org.eclipse.titan.designer.AST.Reference) Definitions(org.eclipse.titan.designer.AST.TTCN3.definitions.Definitions) ArrayList(java.util.ArrayList) MessageConsoleStream(org.eclipse.ui.console.MessageConsoleStream) DeleteEdit(org.eclipse.text.edits.DeleteEdit) IProject(org.eclipse.core.resources.IProject) ProjectSourceParser(org.eclipse.titan.designer.parsers.ProjectSourceParser) ImportModule(org.eclipse.titan.designer.AST.TTCN3.definitions.ImportModule) IRegion(org.eclipse.jface.text.IRegion) Module(org.eclipse.titan.designer.AST.Module) ImportModule(org.eclipse.titan.designer.AST.TTCN3.definitions.ImportModule) TTCN3Module(org.eclipse.titan.designer.AST.TTCN3.definitions.TTCN3Module) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) HashSet(java.util.HashSet) Location(org.eclipse.titan.designer.AST.Location)

Aggregations

ImportModule (org.eclipse.titan.designer.AST.TTCN3.definitions.ImportModule)9 ArrayList (java.util.ArrayList)7 Module (org.eclipse.titan.designer.AST.Module)7 Location (org.eclipse.titan.designer.AST.Location)6 HashSet (java.util.HashSet)5 IFile (org.eclipse.core.resources.IFile)5 TTCN3Module (org.eclipse.titan.designer.AST.TTCN3.definitions.TTCN3Module)5 ProjectSourceParser (org.eclipse.titan.designer.parsers.ProjectSourceParser)5 TreeSet (java.util.TreeSet)3 FriendModule (org.eclipse.titan.designer.AST.TTCN3.definitions.FriendModule)3 MessageConsoleStream (org.eclipse.ui.console.MessageConsoleStream)3 IProject (org.eclipse.core.resources.IProject)2 IResource (org.eclipse.core.resources.IResource)2 IRegion (org.eclipse.jface.text.IRegion)2 DeleteEdit (org.eclipse.text.edits.DeleteEdit)2 InsertEdit (org.eclipse.text.edits.InsertEdit)2 MultiTextEdit (org.eclipse.text.edits.MultiTextEdit)2 Reference (org.eclipse.titan.designer.AST.Reference)2 IAppendableSyntax (org.eclipse.titan.designer.AST.TTCN3.IAppendableSyntax)2 Definitions (org.eclipse.titan.designer.AST.TTCN3.definitions.Definitions)2