From 694f0acd465f9428c37500a5f56ac783b3aaf506 Mon Sep 17 00:00:00 2001 From: Jussi Koskela Date: Mon, 20 Mar 2017 15:04:31 +0200 Subject: [PATCH] Not possible to open declaration of SCL module from relative path (F3) Resolve absolute path of SCL module when user presses F3 on import/include that uses relative path. Refactored absolute path resolving to static utility function. refs #7101 Change-Id: I21cadedd6b8baf9ec4d7fae25cd4a0135836a439 --- .../scl/compiler/compilation/Elaboration.java | 35 +++------------ .../module/InvalidModulePathException.java | 11 +++++ .../scl/compiler/module/ModuleUtils.java | 30 +++++++++++++ .../completion/SCLTextEditorEnvironment.java | 44 +++++-------------- .../scl/ui/editor2/OpenDeclaration.java | 16 ++++++- 5 files changed, 72 insertions(+), 64 deletions(-) create mode 100644 bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/InvalidModulePathException.java create mode 100644 bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/ModuleUtils.java diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java index 5461d7a29..898f6c0a5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java @@ -92,6 +92,8 @@ import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository; import org.simantics.scl.compiler.internal.parsing.types.TypeAst; import org.simantics.scl.compiler.module.ConcreteModule; import org.simantics.scl.compiler.module.ImportDeclaration; +import org.simantics.scl.compiler.module.InvalidModulePathException; +import org.simantics.scl.compiler.module.ModuleUtils; import org.simantics.scl.compiler.module.repository.ImportFailure; import org.simantics.scl.compiler.module.repository.ImportFailureException; import org.simantics.scl.compiler.types.TCon; @@ -184,14 +186,16 @@ public class Elaboration { ArrayList absoluteImports = new ArrayList(relativeImports.size()); for(ImportDeclaration relativeImport : relativeImports) { if(relativeImport.moduleName.startsWith(".")) { - String absoluteModuleName = convertRelativeModulePath(relativeImport.location, relativeImport.moduleName); - if(absoluteModuleName != null) { + try { + String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName); ImportDeclaration absoluteImport = new ImportDeclaration( absoluteModuleName, relativeImport.localName, relativeImport.reexport, relativeImport.spec); absoluteImport.location = relativeImport.location; absoluteImports.add(absoluteImport); - } + } catch (InvalidModulePathException e) { + errorLog.log(relativeImport.location, e.getMessage()); + } } else absoluteImports.add(relativeImport); @@ -199,31 +203,6 @@ public class Elaboration { return absoluteImports; } - private String convertRelativeModulePath(long location, String relativeModuleName) { - String originalRelativeModuleName = relativeModuleName; - int p = moduleName.lastIndexOf('/'); - String parentPackage = p < 0 ? "" : moduleName.substring(0, p); - while(relativeModuleName.startsWith(".")) { - if(relativeModuleName.startsWith("./")) { - relativeModuleName = relativeModuleName.substring(2); - } - else if(relativeModuleName.startsWith("../")) { - relativeModuleName = relativeModuleName.substring(3); - if(parentPackage.isEmpty()) { - errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + "."); - return null; - } - p = parentPackage.lastIndexOf('/'); - parentPackage = p < 0 ? "" : parentPackage.substring(0, p); - } - else { - errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax."); - return null; - } - } - return parentPackage + "/" + relativeModuleName; - } - public void addTypesToEnvironment( ArrayList dataTypesAst, ArrayList typeAliasesAst, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/InvalidModulePathException.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/InvalidModulePathException.java new file mode 100644 index 000000000..5fe467720 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/InvalidModulePathException.java @@ -0,0 +1,11 @@ +package org.simantics.scl.compiler.module; + +public class InvalidModulePathException extends Exception { + + private static final long serialVersionUID = 4981982587509793105L; + + public InvalidModulePathException(String message) { + super(message); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/ModuleUtils.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/ModuleUtils.java new file mode 100644 index 000000000..f5ae62ab8 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/ModuleUtils.java @@ -0,0 +1,30 @@ +package org.simantics.scl.compiler.module; + +public class ModuleUtils { + public static String resolveAbsolutePath(String moduleName, String relativeModuleName) throws InvalidModulePathException { + if (relativeModuleName.startsWith(".")) { + String originalRelativeModuleName = relativeModuleName; + int p = moduleName.lastIndexOf('/'); + String parentPackage = p < 0 ? "" : moduleName.substring(0, p); + while(relativeModuleName.startsWith(".")) { + if(relativeModuleName.startsWith("./")) { + relativeModuleName = relativeModuleName.substring(2); + } + else if(relativeModuleName.startsWith("../")) { + relativeModuleName = relativeModuleName.substring(3); + if(parentPackage.isEmpty()) { + throw new InvalidModulePathException("Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + "."); + } + p = parentPackage.lastIndexOf('/'); + parentPackage = p < 0 ? "" : parentPackage.substring(0, p); + } + else { + throw new InvalidModulePathException("Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax."); + } + } + return parentPackage + "/" + relativeModuleName; + } else { + return relativeModuleName; + } + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLTextEditorEnvironment.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLTextEditorEnvironment.java index 9006f3cc2..de335f0f9 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLTextEditorEnvironment.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLTextEditorEnvironment.java @@ -18,7 +18,9 @@ import org.simantics.scl.compiler.errors.Failable; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl; import org.simantics.scl.compiler.module.ImportDeclaration; +import org.simantics.scl.compiler.module.InvalidModulePathException; import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.ModuleUtils; import org.simantics.scl.compiler.module.repository.ImportFailureException; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.osgi.SCLOsgi; @@ -103,44 +105,18 @@ public class SCLTextEditorEnvironment { private ArrayList processRelativeImports(List relativeImports) { ArrayList absoluteImports = new ArrayList(relativeImports.size()); for(ImportDeclaration relativeImport : relativeImports) { - if(relativeImport.moduleName.startsWith(".")) { - String absoluteModuleName = convertRelativeModulePath(relativeImport.moduleName); - if(absoluteModuleName != null) - absoluteImports.add(new ImportDeclaration( - absoluteModuleName, relativeImport.localName, - relativeImport.reexport, relativeImport.spec)); - } - else - absoluteImports.add(relativeImport); + try { + String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName); + absoluteImports.add(new ImportDeclaration( + absoluteModuleName, relativeImport.localName, + relativeImport.reexport, relativeImport.spec)); + } catch (InvalidModulePathException e) { + // Nothing to do + } } return absoluteImports; } - private String convertRelativeModulePath(String relativeModuleName) { - String originalRelativeModuleName = relativeModuleName; - int p = moduleName.lastIndexOf('/'); - String parentPackage = p < 0 ? "" : moduleName.substring(0, p); - while(relativeModuleName.startsWith(".")) { - if(relativeModuleName.startsWith("./")) { - relativeModuleName = relativeModuleName.substring(2); - } - else if(relativeModuleName.startsWith("../")) { - relativeModuleName = relativeModuleName.substring(3); - if(parentPackage.isEmpty()) { - System.err.println("Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + "."); - return null; - } - p = parentPackage.lastIndexOf('/'); - parentPackage = p < 0 ? "" : parentPackage.substring(0, p); - } - else { - System.err.println("Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax."); - return null; - } - } - return parentPackage + "/" + relativeModuleName; - } - private static final Comparator COMPARATOR = new Comparator() { @Override diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java index cd59c874d..4b6818ab7 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java @@ -9,6 +9,10 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.compiler.module.InvalidModulePathException; +import org.simantics.scl.compiler.module.ModuleUtils; +import org.simantics.scl.compiler.source.ModuleSource; +import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment; public class OpenDeclaration extends AbstractHandler { @@ -83,8 +87,16 @@ public class OpenDeclaration extends AbstractHandler { if(lineAtCaret.startsWith("import ") || lineAtCaret.startsWith("include ")) { int p1 = lineAtCaret.indexOf('"', 6); int p2 = lineAtCaret.indexOf('"', p1+1); - String moduleName = lineAtCaret.substring(p1+1, p2); - OpenSCLModule.openModule(moduleName); + SCLModuleEditorInput input = (SCLModuleEditorInput)moduleEditor.getEditorInput(); + try { + String moduleName = ModuleUtils.resolveAbsolutePath(input.getModuleName(), lineAtCaret.substring(p1+1, p2)); + ModuleSource source = SCLOsgi.SOURCE_REPOSITORY.getModuleSource(moduleName, null); + if (source != null) { + OpenSCLModule.openModule(moduleName); + } + } catch (InvalidModulePathException e) { + // Nothing to do + } } else { // Try to find an identifier at caret -- 2.43.2