From: Hannu Niemistö Date: Wed, 1 Feb 2017 14:40:11 +0000 (+0200) Subject: Added module header feature to SCL language. X-Git-Tag: v1.28.0~88^2 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=66ced93f835205135a84fea73b2fbb8e9d610f7e;p=simantics%2Fplatform.git Added module header feature to SCL language. Module header must be in the beginning of the module. However, comments are allowed before the header. Header has the following form: module { field = value, field = value } Currently field name classLoader is supported. It makes it possible to specify which classLoader is used to resolve importJava declarations. module { classLoader = "my.bundle.name.somewhere" } refs #6931 Change-Id: Ibca2152597a738d1e4641cf6262af06069b38af5 --- diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java index f090be06c..3fc0d46fa 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java @@ -10,9 +10,12 @@ import org.simantics.scl.compiler.source.repository.ModuleSourceRepository; public class Activator implements BundleActivator { + private static BundleContext context; + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void start(BundleContext context) throws Exception { + Activator.context = context; Hashtable properties = new Hashtable(); context.registerService(ModuleSourceRepository.class, OntologyModuleSourceRepository.INSTANCE, properties); @@ -23,5 +26,7 @@ public class Activator implements BundleActivator { public void stop(BundleContext context) throws Exception { } - + public static BundleContext getContext() { + return context; + } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index 07af09e55..c75f7a941 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -15,11 +15,14 @@ import org.simantics.db.procedure.SyncListener; import org.simantics.db.request.Read; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingUtils; +import org.simantics.modeling.internal.Activator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.module.repository.UpdateListener.Observable; import org.simantics.scl.compiler.source.ModuleSource; import org.simantics.scl.compiler.source.StringModuleSource; import org.simantics.scl.compiler.source.repository.ModuleSourceRepository; +import org.simantics.scl.osgi.internal.OsgiJavaReferenceValidatorFactory; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.tuple.Tuple0; import org.simantics.structural2.utils.StructuralUtils; @@ -29,6 +32,8 @@ import gnu.trove.set.hash.THashSet; public enum GraphModuleSourceRepository implements ModuleSourceRepository { INSTANCE; + + private static final OsgiJavaReferenceValidatorFactory REFERENCE_VALIDATOR_FACTORY = new OsgiJavaReferenceValidatorFactory(Activator.getContext().getBundle()); @Override public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) { @@ -123,6 +128,11 @@ public enum GraphModuleSourceRepository implements ModuleSourceRepository { e.printStackTrace(); } } + + @Override + public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() { + return REFERENCE_VALIDATOR_FACTORY; + } } static class ReadModuleSource extends UnaryRead { diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java index 17aba97ea..1c8c91927 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java @@ -312,4 +312,9 @@ public class OntologyModule extends LazyModule { public String toString() { return new StringBuilder().append("OntologyModule ").append(getName()).toString(); } + + @Override + public ClassLoader getParentClassLoader() { + return getClass().getClassLoader(); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DeclarationClassification.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DeclarationClassification.java index 7c6d53ac8..652adf93e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DeclarationClassification.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DeclarationClassification.java @@ -23,6 +23,7 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst; import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst; import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst; import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst; +import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader; import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst; import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst; @@ -38,6 +39,7 @@ import org.simantics.scl.compiler.module.ImportDeclaration; import gnu.trove.map.hash.THashMap; public class DeclarationClassification { + DModuleHeader moduleHeader; ArrayList importsAst = new ArrayList(); ArrayList dataTypesAst = new ArrayList(); ArrayList typeAliasesAst = new ArrayList(); @@ -106,6 +108,8 @@ public class DeclarationClassification { handle((DMappingRelationAst)declaration); else if(declaration instanceof DRelationAst) handle((DRelationAst)declaration); + else if(declaration instanceof DModuleHeader) + handle((DModuleHeader)declaration); else throw new InternalCompilerError("Unknown declaration " + declaration.getClass().getSimpleName()); } @@ -380,6 +384,10 @@ public class DeclarationClassification { mappingRelationsAst.add(declaration); } + public void handle(DModuleHeader declaration) { + moduleHeader = declaration; + } + public void addValueDocumentation(String valueName, DDocumentationAst documentation) { DDocumentationAst oldDoc = valueDocumentation.put(valueName, documentation); if(oldDoc != null) { 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 0971641e8..5461d7a29 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 @@ -59,6 +59,7 @@ import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor; import org.simantics.scl.compiler.internal.codegen.utils.Constants; @@ -68,6 +69,7 @@ import org.simantics.scl.compiler.internal.deriving.InstanceDeriver; import org.simantics.scl.compiler.internal.deriving.InstanceDerivers; import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; +import org.simantics.scl.compiler.internal.header.ModuleHeader; import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst; import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst; @@ -116,7 +118,9 @@ public class Elaboration { private final CompilationContext compilationContext; private final ErrorLog errorLog; private final String moduleName; + private final ModuleHeader moduleHeader; private final ArrayList importsAst; + private final JavaReferenceValidatorFactory jrvFactory; final JavaReferenceValidator javaReferenceValidator; private final ValueRepository valueDefinitionsAst; private final RelationRepository relationDefinitionsAst; @@ -131,18 +135,23 @@ public class Elaboration { THashMap classRefs = new THashMap(); THashMap branchPoints; - @SuppressWarnings("unchecked") public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory, - String moduleName, ArrayList importsAst, - JavaReferenceValidator javaReferenceValidator, + String moduleName, ModuleHeader moduleHeader, ArrayList importsAst, + JavaReferenceValidatorFactory jrvFactory, ValueRepository valueDefinitionsAst, RelationRepository relationDefinitionsAst) { this.compilationContext = compilationContext; this.errorLog = compilationContext.errorLog; this.moduleName = moduleName; + this.moduleHeader = moduleHeader; importsAst = processRelativeImports(importsAst); this.importsAst = importsAst; - this.javaReferenceValidator = (JavaReferenceValidator)javaReferenceValidator; + this.jrvFactory = jrvFactory; + this.javaReferenceValidator = moduleHeader == null || moduleHeader.classLoader == null + ? jrvFactory.getDefaultJavaReferenceValidator() + : jrvFactory.getJavaReferenceValidator(moduleHeader.classLoader); + if(javaReferenceValidator == null) + errorLog.log(moduleHeader.classLoaderLocation, "Didn't find the specified class loader."); this.valueDefinitionsAst = valueDefinitionsAst; this.relationDefinitionsAst = relationDefinitionsAst; @@ -653,15 +662,12 @@ public class Elaboration { if(annotations != null) { for(DAnnotationAst annotation : annotations) if(annotation.id.text.equals("@JavaName")) { - Expression p0 = annotation.parameters[0]; - if(p0 instanceof EVar) - javaName = ((EVar)p0).name; - else if(p0 instanceof ELiteral) { - ELiteral lit = (ELiteral)p0; - javaName = ((StringConstant)lit.getValue()).getValue(); - } + String temp = AnnotationUtils.processStringAnnotation(errorLog, annotation); + if(temp != null) + javaName = temp; } else if(annotation.id.text.equals("@private")) { + AnnotationUtils.processTagAnnotation(errorLog, annotation); isPrivate = true; } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java index 29136b609..65e89edf1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java @@ -8,9 +8,12 @@ import java.util.Map; import org.simantics.scl.compiler.environment.EnvironmentFactory; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; +import org.simantics.scl.compiler.internal.header.ModuleHeader; import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl; +import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions; import org.simantics.scl.compiler.module.ConcreteModule; import org.simantics.scl.compiler.module.options.ModuleCompilationOptions; import org.simantics.scl.compiler.top.ModuleInitializer; @@ -29,8 +32,11 @@ public class SCLCompiler { private CompilationTimer timer; private ModuleCompilationOptions options; - public SCLCompiler(ModuleCompilationOptions options) { + JavaReferenceValidatorFactory jrvFactory; + + public SCLCompiler(ModuleCompilationOptions options, JavaReferenceValidatorFactory jrvFactory) { this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options; + this.jrvFactory = jrvFactory; } @SuppressWarnings("unchecked") @@ -38,6 +44,7 @@ public class SCLCompiler { if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming(); try { SCLParserImpl parser = new SCLParserImpl(sourceReader); + parser.setParserOptions(SCLParserOptions.MODULE_DEFAULT); if(!parser.isEmpty()) for(DeclarationAst declaration : (ArrayList)parser.parseModule()) declarations.handle(declaration); @@ -61,16 +68,16 @@ public class SCLCompiler { public void compile( EnvironmentFactory localEnvironmentFactory, - String moduleName, - JavaReferenceValidator javaReferenceValidator) { + String moduleName) { try { if(hasErrors()) return; Elaboration elaboration = new Elaboration(compilationContext, timer, localEnvironmentFactory, moduleName, + ModuleHeader.process(compilationContext.errorLog, declarations.moduleHeader), declarations.importsAst, - javaReferenceValidator, + jrvFactory, declarations.valueDefinitionsAst, declarations.relationDefinitionsAst); if(options.computeCoverage) @@ -159,6 +166,7 @@ public class SCLCompiler { codeGeneration.externalConstants); module.setClasses(classes); + module.setParentClassLoader(elaboration.javaReferenceValidator.getClassLoader()); module.setModuleInitializer(moduleInitializer); module.setBranchPoints(elaboration.branchPoints); if(compilationContext.errorLog.hasErrorsOrWarnings()) diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/annotations/AnnotationUtils.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/annotations/AnnotationUtils.java index fb7334cd2..8cc088b95 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/annotations/AnnotationUtils.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/annotations/AnnotationUtils.java @@ -5,8 +5,30 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst; public class AnnotationUtils { + /** + * Processes an annotation of form + *
@Annotation "text"
+ * or + *
@Annotation text
+ */ + public static String processStringAnnotation(ErrorLog errorLog, DAnnotationAst annotation) { + if(annotation.parameters.length != 1) + errorLog.log(annotation.location, "Expected one string parameter for " + annotation.id.text); + String result = extractString(annotation.parameters[0]); + if(result == null) + errorLog.log(annotation.location, "Expected a string parameter for " + annotation.id.text); + return result; + } + + public static void processTagAnnotation(ErrorLog errorLog, DAnnotationAst annotation) { + if(annotation.parameters.length != 0) + errorLog.log(annotation.location, "Expected no parameters for " + annotation.id.text); + } + public static String extractString(Expression expression) { if(expression instanceof EVar) return ((EVar)expression).name; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java index 7935257ac..14808c820 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java @@ -348,6 +348,8 @@ public class Builtins extends ConcreteModule { addValue("visitBranchPoint", VisitBranchPoint.INSTANCE); } + + setParentClassLoader(getClass().getClassLoader()); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java index cb39346e4..e412a1168 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java @@ -137,6 +137,8 @@ public class JavaModule extends ConcreteModule { "java/lang/Object", "hashCode", Types.NO_EFFECTS, Types.INTEGER, A)); addValue("toString", new JavaMethod(true, "java/lang/Object", "toString", Types.NO_EFFECTS, Types.STRING, A)); + + setParentClassLoader(getClass().getClassLoader()); } static Expression createLiteral(FunctionValue value) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java index 6bdaaea7b..434f2da6e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java @@ -282,6 +282,7 @@ public class MinigraphModule extends ConcreteModule { return new ResourceAttribute(name); } }); + setParentClassLoader(getClass().getClassLoader()); } private static class ResourceAttribute implements SCLEntityType.Attribute { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/DummyJavaReferenceValidator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/DummyJavaReferenceValidator.java index 84289af0d..994e2d63f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/DummyJavaReferenceValidator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/DummyJavaReferenceValidator.java @@ -76,5 +76,10 @@ public enum DummyJavaReferenceValidator implements JavaReferenceValidator { * class is not found. */ ClassRef getClassRef(String className); + + ClassLoader getClassLoader(); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaReferenceValidatorFactory.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaReferenceValidatorFactory.java new file mode 100644 index 000000000..55d42c289 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaReferenceValidatorFactory.java @@ -0,0 +1,6 @@ +package org.simantics.scl.compiler.internal.codegen.types; + +public interface JavaReferenceValidatorFactory { + JavaReferenceValidator getJavaReferenceValidator(String context); + JavaReferenceValidator getDefaultJavaReferenceValidator(); +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/RuntimeJavaReferenceValidator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/RuntimeJavaReferenceValidator.java index 8b36a8148..4ee0ab4f8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/RuntimeJavaReferenceValidator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/RuntimeJavaReferenceValidator.java @@ -14,5 +14,10 @@ public class RuntimeJavaReferenceValidator extends AbstractRuntimeJavaReferenceV public Class findClass(TypeDesc name) { return name.toClass(classLoader); } + + @Override + public ClassLoader getClassLoader() { + return classLoader; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/header/ModuleHeader.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/header/ModuleHeader.java new file mode 100644 index 000000000..c49b49abe --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/header/ModuleHeader.java @@ -0,0 +1,38 @@ +package org.simantics.scl.compiler.internal.header; + +import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils; +import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment; +import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader; + +public class ModuleHeader { + public String classLoader; + public long classLoaderLocation; + + private void read(ErrorLog errorLog, DModuleHeader header) { + for(FieldAssignment assignment : header.fields) + switch(assignment.name) { + case "classLoader": + if(assignment.value == null) + errorLog.log(assignment.location, "Property classLoader needs to be given a string value."); + else { + classLoader = AnnotationUtils.extractString(assignment.value); + if(classLoader == null) + errorLog.log(assignment.value.location, "Expected bundle name here."); + else + classLoaderLocation = assignment.location; + } + break; + default: + errorLog.logWarning(assignment.location, "Unknown module header field was skipped."); + } + } + + public static ModuleHeader process(ErrorLog errorLog, DModuleHeader header) { + if(header == null) + return null; + ModuleHeader result = new ModuleHeader(); + result.read(errorLog, header); + return result; + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DModuleHeader.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DModuleHeader.java new file mode 100644 index 000000000..25d14e2d2 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DModuleHeader.java @@ -0,0 +1,36 @@ +package org.simantics.scl.compiler.internal.parsing.declarations; + +import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor; +import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment; + + + +public class DModuleHeader extends DeclarationAst { + public final FieldAssignment[] fields; + + public DModuleHeader(FieldAssignment[] fields) { + this.fields = fields; + } + + @Override + public void toString(int indentation, StringBuilder b) { + for(int i=0;i declarations = new ArrayList(length()/2+1); - for(int i=0;i classes = Collections.emptyMap(); + ClassLoader parentClassLoader; ModuleInitializer moduleInitializer; protected Documentation documentation; @@ -278,4 +279,15 @@ public class ConcreteModule implements Module { public CompilationError[] getWarnings() { return warnings; } + + @Override + public ClassLoader getParentClassLoader() { + return parentClassLoader; + } + + public void setParentClassLoader(ClassLoader parentClassLoader) { + if(parentClassLoader == null) + throw new NullPointerException(); + this.parentClassLoader = parentClassLoader; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/Module.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/Module.java index 180509521..6f13ed426 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/Module.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/Module.java @@ -54,5 +54,5 @@ public interface Module { void dispose(); CompilationError[] getWarnings(); - + ClassLoader getParentClassLoader(); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java index 7170b992b..40c69f434 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java @@ -173,7 +173,7 @@ public class ModuleRepository { if(parentModule != null) parentModules.add(parentModule); }*/ - RuntimeModule rm = new RuntimeModule(module, parentModules, source.getClassLoader()); + RuntimeModule rm = new RuntimeModule(module, parentModules, module.getParentClassLoader()); ModuleInitializer initializer = module.getModuleInitializer(); if(initializer != null) try { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java index 2415e6520..93ecb2f17 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java @@ -209,6 +209,8 @@ public class RuntimeModule { public RuntimeModule(Module module, RuntimeModuleMap parentModuleMap, ClassLoader parentClassLoader) { + if(parentClassLoader == null) + throw new NullPointerException(); this.module = module; this.parentModuleMap = parentModuleMap; this.classLoader = new ModuleClassLoader(parentClassLoader); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java index 4f22022e5..9a6f4c97f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java @@ -11,6 +11,7 @@ import org.simantics.scl.compiler.errors.Failable; import org.simantics.scl.compiler.errors.Failure; import org.simantics.scl.compiler.errors.Success; import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator; import org.simantics.scl.compiler.module.ImportDeclaration; import org.simantics.scl.compiler.module.Module; @@ -80,7 +81,7 @@ public abstract class TextualModuleSource implements ModuleSource { @SuppressWarnings("unchecked") @Override public Failable compileModule(final ModuleRepository environment, final UpdateListener listener, ModuleCompilationOptions options) { - SCLCompiler compiler = new SCLCompiler(options); + SCLCompiler compiler = new SCLCompiler(options, getJavaReferenceValidatorFactory()); try { compiler.addSource(getSourceReader(listener)); compiler.compile( @@ -88,8 +89,7 @@ public abstract class TextualModuleSource implements ModuleSource { environment, getBuiltinImports(listener), listener), - moduleName, - getJavaReferenceValidator()); + moduleName); if(compiler.getErrorLog().hasNoErrors()) return new Success(compiler.getModule()); else { @@ -102,6 +102,21 @@ public abstract class TextualModuleSource implements ModuleSource { } } + public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() { + return new JavaReferenceValidatorFactory() { + + @Override + public JavaReferenceValidator getJavaReferenceValidator(String context) { + return (JavaReferenceValidator)TextualModuleSource.this.getJavaReferenceValidator(); + } + + @Override + public JavaReferenceValidator getDefaultJavaReferenceValidator() { + return (JavaReferenceValidator)TextualModuleSource.this.getJavaReferenceValidator(); + } + }; + } + @Override public double getPriority() { return priority; diff --git a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java index 244c7463f..3213cf9b5 100644 --- a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java +++ b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java @@ -15,6 +15,7 @@ import java.util.Arrays; import org.eclipse.core.runtime.FileLocator; import org.osgi.framework.Bundle; import org.osgi.framework.wiring.BundleWiring; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; import org.simantics.scl.compiler.module.ImportDeclaration; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.source.EncodedTextualModuleSource; @@ -161,4 +162,7 @@ public class BundleModuleSource extends EncodedTextualModuleSource implements Up } } + public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() { + return new OsgiJavaReferenceValidatorFactory(bundle); + } } diff --git a/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/OsgiJavaReferenceValidatorFactory.java b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/OsgiJavaReferenceValidatorFactory.java new file mode 100644 index 000000000..03524e883 --- /dev/null +++ b/bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/OsgiJavaReferenceValidatorFactory.java @@ -0,0 +1,58 @@ +package org.simantics.scl.osgi.internal; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.wiring.BundleWiring; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator; +import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory; +import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator; +import org.simantics.scl.compiler.types.Type; + +public class OsgiJavaReferenceValidatorFactory implements JavaReferenceValidatorFactory { + + private final Bundle bundle; + + public OsgiJavaReferenceValidatorFactory(Bundle bundle) { + this.bundle = bundle; + } + + private static ClassLoader getClassLoader(Bundle bundle) { + if(bundle.getSymbolicName().equals("org.simantics.scl.runtime")) + return Type.class.getClassLoader(); + else { + BundleWiring wiring = bundle.adapt(BundleWiring.class); + if(wiring != null) + return wiring.getClassLoader(); + throw new InternalCompilerError("Cannot get the class loader for bundle " + bundle.getSymbolicName() + "."); + } + } + + private static JavaReferenceValidator getJavaReferenceValidator(Bundle bundle) { + if(bundle == null) + return null; + return (JavaReferenceValidator) + (JavaReferenceValidator)new RuntimeJavaReferenceValidator(getClassLoader(bundle)); + } + + private static Bundle getBundle(BundleContext bundleContext, String symbolicName) { + Bundle result = null; + for (Bundle candidate : bundleContext.getBundles()) + if (candidate.getSymbolicName().equals(symbolicName)) + if (result == null || result.getVersion().compareTo(candidate.getVersion()) < 0) + result = candidate; + return result; + } + + @Override + public JavaReferenceValidator getJavaReferenceValidator(String bundleName) { + System.out.println("getJavaReferenceValidator(" + bundleName + ")"); + return getJavaReferenceValidator(getBundle(bundle.getBundleContext(), bundleName)); + } + + @Override + public JavaReferenceValidator getDefaultJavaReferenceValidator() { + return getJavaReferenceValidator(bundle); + } + +}