]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / Elaboration.java
index f5834aef1ac949b92a74a5c83c3cd2265a0f0fd5..898f6c0a5680c88bad669e56c5395a5fe65d0164 100644 (file)
@@ -31,9 +31,11 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.EVar;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils;
 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
 import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration;
 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
+import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty;
 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
@@ -57,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;
@@ -66,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;
@@ -88,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;
@@ -114,7 +120,9 @@ public class Elaboration {
     private final CompilationContext compilationContext;
     private final ErrorLog errorLog;
     private final String moduleName;
+    private final ModuleHeader moduleHeader;
     private final ArrayList<ImportDeclaration> importsAst;
+    private final JavaReferenceValidatorFactory jrvFactory;
     final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
     private final ValueRepository valueDefinitionsAst;
     private final RelationRepository relationDefinitionsAst;
@@ -129,18 +137,23 @@ public class Elaboration {
     THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
     THashMap<String, BranchPoint[]> branchPoints; 
     
-    @SuppressWarnings("unchecked")
     public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
-            String moduleName, ArrayList<ImportDeclaration> importsAst,
-            JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
+            String moduleName, ModuleHeader moduleHeader, ArrayList<ImportDeclaration> 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<Object, Object, Object, Object>)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;
 
@@ -173,14 +186,16 @@ public class Elaboration {
         ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(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);
@@ -188,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<DDataAst> dataTypesAst,
             ArrayList<DTypeAst> typeAliasesAst,
@@ -310,7 +300,7 @@ public class Elaboration {
             }
         }.findComponents();
         
-        if(errorLog.isEmpty()) {
+        if(errorLog.hasNoErrors()) {
             for(DTypeAst typeAlias : orderedTypeAliases) {
                 TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name);
                 TypeTranslationContext context = createTypeTranslationContext();
@@ -651,15 +641,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;
                     }
             }
@@ -1212,7 +1199,19 @@ public class Elaboration {
             value.addProperty(PrivateProperty.INSTANCE);
         }
         else if(annotation.id.text.equals("@deprecated")) {
-            // TODO
+            String description = "";
+            if(annotation.parameters.length > 0) {
+                if(annotation.parameters.length > 1)
+                    errorLog.log(annotation.location, "Invalid number of parameters, expected one string.");
+                else {
+                    String temp = AnnotationUtils.extractString(annotation.parameters[0]);
+                    if(temp == null)
+                        errorLog.log(annotation.location, "Invalid parameter, expected one string.");
+                    else
+                        description = temp;
+                }
+            }
+            value.addProperty(new DeprecatedProperty(description));
         }
         else
             errorLog.log(annotation.location, "Unknown annotation.");