diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index ba45b3bd0c..19acb14b47 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -64,7 +64,7 @@ Model: /** * Import declaration. */ -Import: 'import' reactorClasses+=ImportedReactor (',' reactorClasses+=ImportedReactor)* 'from' importURI=STRING ';'?; +Import: 'import' reactorClasses+=ImportedReactor (',' reactorClasses+=ImportedReactor)* 'from' (importURI=STRING | importPackage=LIB_PATH) ';'?; ReactorDecl: Reactor | ImportedReactor; @@ -431,6 +431,8 @@ terminal STRING: '"' ( '\\' . | !('\\' | '"' | '\t' | '\r' | '\n') )* '"' | '"""' -> '"""' ; +terminal LIB_PATH: '<' ( '\\' . | !('\\' | '"' | '\t' | '\r' | '\n') )* '>'; + terminal CHAR_LIT: "'" ( '\\' . | !('\\' | "'" | '\t' | '\r' | '\n') ) "'"; terminal ANY_OTHER: .; diff --git a/core/src/main/java/org/lflang/ast/IsEqual.java b/core/src/main/java/org/lflang/ast/IsEqual.java index 8eec27a430..afe1568f96 100644 --- a/core/src/main/java/org/lflang/ast/IsEqual.java +++ b/core/src/main/java/org/lflang/ast/IsEqual.java @@ -99,6 +99,7 @@ public Boolean caseModel(Model object) { public Boolean caseImport(Import object) { return new ComparisonMachine<>(object, Import.class) .equalAsObjects(Import::getImportURI) + .equalAsObjects(Import::getImportPackage) .listsEquivalent(Import::getReactorClasses) .conclusion; } diff --git a/core/src/main/java/org/lflang/ast/ToLf.java b/core/src/main/java/org/lflang/ast/ToLf.java index 3b1b1e48df..dda8524aa7 100644 --- a/core/src/main/java/org/lflang/ast/ToLf.java +++ b/core/src/main/java/org/lflang/ast/ToLf.java @@ -398,7 +398,8 @@ public MalleableString caseImport(Import object) { // TODO: This is a place where we can use conditional parentheses. .append(list(", ", "", "", false, true, true, object.getReactorClasses())) .append(" from \"") - .append(object.getImportURI()) + // TODO: Check if angular brackets (< >) are required + .append(object.getImportURI() != null ? object.getImportURI() : object.getImportPackage()) .append("\"") .get(); } diff --git a/core/src/main/java/org/lflang/ast/ToSExpr.java b/core/src/main/java/org/lflang/ast/ToSExpr.java index a514d98234..dd013dd9fa 100644 --- a/core/src/main/java/org/lflang/ast/ToSExpr.java +++ b/core/src/main/java/org/lflang/ast/ToSExpr.java @@ -217,7 +217,8 @@ public SExpr caseImport(Import object) { // reactorClasses+=ImportedReactor)* 'from' importURI=STRING ';'?; return sList( "import", - new SAtom<>(object.getImportURI()), + // TODO: Check if angular brackets (< >) are required + new SAtom<>(object.getImportURI() != null ? object.getImportURI() : object.getImportPackage()), sList("reactors", object.getReactorClasses())); } diff --git a/core/src/main/java/org/lflang/scoping/LFScopeProviderImpl.java b/core/src/main/java/org/lflang/scoping/LFScopeProviderImpl.java index 3455c1d822..7f55a01ef5 100644 --- a/core/src/main/java/org/lflang/scoping/LFScopeProviderImpl.java +++ b/core/src/main/java/org/lflang/scoping/LFScopeProviderImpl.java @@ -26,16 +26,23 @@ package org.lflang.scoping; import static java.util.Collections.emptyList; -import static org.lflang.ast.ASTUtils.*; +import static org.lflang.ast.ASTUtils.allActions; +import static org.lflang.ast.ASTUtils.allInputs; +import static org.lflang.ast.ASTUtils.allOutputs; +import static org.lflang.ast.ASTUtils.allParameters; +import static org.lflang.ast.ASTUtils.allTimers; +import static org.lflang.ast.ASTUtils.allWatchdogs; +import static org.lflang.ast.ASTUtils.toDefinition; -import com.google.inject.Inject; import java.util.ArrayList; + import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.xtext.naming.SimpleNameProvider; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.Scopes; import org.eclipse.xtext.scoping.impl.SelectableBasedScope; + import org.lflang.lf.Assignment; import org.lflang.lf.Connection; import org.lflang.lf.Deadline; @@ -51,6 +58,8 @@ import org.lflang.lf.VarRef; import org.lflang.lf.Watchdog; +import com.google.inject.Inject; + /** * This class enforces custom rules. In particular, it resolves references to parameters, ports, * actions, and timers. Ports can be referenced across at most one level of hierarchy. Parameters, @@ -104,7 +113,9 @@ public IScope getScope(EObject context, EReference reference) { * statement. */ protected IScope getScopeForImportedReactor(ImportedReactor context, EReference reference) { - String importURI = ((Import) context.eContainer()).getImportURI(); + String importURI = ((Import) context.eContainer()).getImportURI() != null + ? ((Import) context.eContainer()).getImportURI() + : ((Import) context.eContainer()).getImportPackage().replace("<", "").replace(">", ""); var importedURI = scopeProvider.resolve(importURI == null ? "" : importURI, context.eResource()); if (importedURI != null) {