1 package org.simantics.scl.compiler.compilation;
3 import java.util.ArrayList;
4 import java.util.Iterator;
7 import org.cojen.classfile.TypeDesc;
8 import org.simantics.scl.compiler.common.datatypes.Constructor;
9 import org.simantics.scl.compiler.common.names.Name;
10 import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
11 import org.simantics.scl.compiler.constants.SCLConstructor;
12 import org.simantics.scl.compiler.constants.StringConstant;
13 import org.simantics.scl.compiler.constants.generic.CallJava;
14 import org.simantics.scl.compiler.constants.generic.ClassRef;
15 import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
16 import org.simantics.scl.compiler.constants.generic.MethodRef;
17 import org.simantics.scl.compiler.constants.generic.OutputFilter;
18 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
19 import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
20 import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
21 import org.simantics.scl.compiler.constants.generic.StackItem;
22 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
23 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
24 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
25 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
26 import org.simantics.scl.compiler.elaboration.expressions.EApply;
27 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
28 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
30 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
31 import org.simantics.scl.compiler.elaboration.expressions.EVar;
32 import org.simantics.scl.compiler.elaboration.expressions.Expression;
33 import org.simantics.scl.compiler.elaboration.expressions.Variable;
34 import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils;
35 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
36 import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration;
37 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
38 import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty;
39 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
40 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
41 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
42 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
43 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
44 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
45 import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
46 import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod;
47 import org.simantics.scl.compiler.elaboration.query.Query;
48 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
49 import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation;
50 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
51 import org.simantics.scl.compiler.elaboration.rules.SectionName;
52 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
53 import org.simantics.scl.compiler.environment.AmbiguousNameException;
54 import org.simantics.scl.compiler.environment.Environment;
55 import org.simantics.scl.compiler.environment.EnvironmentFactory;
56 import org.simantics.scl.compiler.environment.Environments;
57 import org.simantics.scl.compiler.errors.ErrorLog;
58 import org.simantics.scl.compiler.errors.Locations;
59 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
60 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
61 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
62 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
63 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
64 import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
65 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
66 import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
67 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
68 import org.simantics.scl.compiler.internal.deriving.InstanceDeriver;
69 import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
70 import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
71 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
72 import org.simantics.scl.compiler.internal.header.ModuleHeader;
73 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
74 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
75 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
76 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
77 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
78 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
79 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
80 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
81 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
85 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
86 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
87 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
88 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst;
89 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
90 import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository;
91 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
92 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
93 import org.simantics.scl.compiler.module.ConcreteModule;
94 import org.simantics.scl.compiler.module.ImportDeclaration;
95 import org.simantics.scl.compiler.module.InvalidModulePathException;
96 import org.simantics.scl.compiler.module.ModuleUtils;
97 import org.simantics.scl.compiler.module.repository.ImportFailure;
98 import org.simantics.scl.compiler.module.repository.ImportFailureException;
99 import org.simantics.scl.compiler.types.TCon;
100 import org.simantics.scl.compiler.types.TForAll;
101 import org.simantics.scl.compiler.types.TFun;
102 import org.simantics.scl.compiler.types.TPred;
103 import org.simantics.scl.compiler.types.TVar;
104 import org.simantics.scl.compiler.types.Type;
105 import org.simantics.scl.compiler.types.Types;
106 import org.simantics.scl.compiler.types.kinds.Kind;
107 import org.simantics.scl.compiler.types.kinds.Kinds;
108 import org.simantics.scl.compiler.types.util.MultiFunction;
109 import org.simantics.scl.runtime.profiling.BranchPoint;
111 import gnu.trove.list.array.TIntArrayList;
112 import gnu.trove.map.hash.THashMap;
113 import gnu.trove.map.hash.TObjectIntHashMap;
114 import gnu.trove.procedure.TObjectObjectProcedure;
115 import gnu.trove.set.hash.THashSet;
116 import gnu.trove.set.hash.TIntHashSet;
118 public class Elaboration {
120 private final CompilationContext compilationContext;
121 private final ErrorLog errorLog;
122 private final String moduleName;
123 private final ModuleHeader moduleHeader;
124 private final ArrayList<ImportDeclaration> importsAst;
125 private final JavaReferenceValidatorFactory jrvFactory;
126 final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
127 private final ValueRepository valueDefinitionsAst;
128 private final RelationRepository relationDefinitionsAst;
131 ConcreteModule module;
132 Environment importedEnvironment;
133 ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
135 JavaTypeTranslator javaTypeTranslator;
136 ArrayList<StandardTypeConstructor> dataTypes = new ArrayList<StandardTypeConstructor>();
137 THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
138 THashMap<String, BranchPoint[]> branchPoints;
140 public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
141 String moduleName, ModuleHeader moduleHeader, ArrayList<ImportDeclaration> importsAst,
142 JavaReferenceValidatorFactory jrvFactory,
143 ValueRepository valueDefinitionsAst,
144 RelationRepository relationDefinitionsAst) {
145 this.compilationContext = compilationContext;
146 this.errorLog = compilationContext.errorLog;
147 this.moduleName = moduleName;
148 this.moduleHeader = moduleHeader;
149 importsAst = processRelativeImports(importsAst);
150 this.importsAst = importsAst;
151 this.jrvFactory = jrvFactory;
152 this.javaReferenceValidator = moduleHeader == null || moduleHeader.classLoader == null
153 ? jrvFactory.getDefaultJavaReferenceValidator()
154 : jrvFactory.getJavaReferenceValidator(moduleHeader.classLoader);
155 if(javaReferenceValidator == null)
156 errorLog.log(moduleHeader.classLoaderLocation, "Didn't find the specified class loader.");
157 this.valueDefinitionsAst = valueDefinitionsAst;
158 this.relationDefinitionsAst = relationDefinitionsAst;
160 module = new ConcreteModule(moduleName);
161 compilationContext.module = module;
162 if(moduleHeader != null && moduleHeader.defaultLocalName != null)
163 module.setDefaultLocalName(moduleHeader.defaultLocalName);
166 timer.suspendTimer();
167 importedEnvironment = localEnvironmentFactory.createEnvironment(
168 importsAst.toArray(new ImportDeclaration[importsAst.size()]));
170 timer.continueTimer();
171 compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
172 } catch (ImportFailureException e) {
173 for(ImportFailure failure : e.failures)
174 errorLog.log(failure.location, failure.toString());
177 for(ImportDeclaration importAst : importsAst)
178 this.module.addDependency(new ImportDeclaration(
179 importAst.moduleName,
180 importAst.reexport ? importAst.localName : null,
183 localEnvironmentFactory.addBuiltinDependencies(module);
184 compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
187 private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
188 ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
189 for(ImportDeclaration relativeImport : relativeImports) {
190 if(relativeImport.moduleName.startsWith(".")) {
192 String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName);
193 ImportDeclaration absoluteImport = new ImportDeclaration(
194 absoluteModuleName, relativeImport.localName,
195 relativeImport.reexport, relativeImport.spec);
196 absoluteImport.location = relativeImport.location;
197 absoluteImports.add(absoluteImport);
198 } catch (InvalidModulePathException e) {
199 errorLog.log(relativeImport.location, e.getMessage());
203 absoluteImports.add(relativeImport);
205 return absoluteImports;
208 public void addTypesToEnvironment(
209 ArrayList<DDataAst> dataTypesAst,
210 ArrayList<DTypeAst> typeAliasesAst,
211 ArrayList<DEffectAst> effectsAst) {
212 for(DDataAst dataType : dataTypesAst) {
213 dataType.parameterKinds = new Kind[dataType.parameters.length];
214 Kind constructorKind = Kinds.STAR;
215 for(int i=dataType.parameters.length-1;i>=0;--i) {
216 Kind kind = Kinds.metaVar();
217 dataType.parameterKinds[i] = kind;
218 constructorKind = Kinds.arrow(kind, constructorKind);
221 StandardTypeConstructor typeConstructor = new StandardTypeConstructor(
222 Types.con(moduleName, dataType.name), constructorKind);
224 NameExistenceChecks.checkIfTypeExists(errorLog,
225 dataType.location, importedEnvironment, dataType.name);
226 if(module.addTypeDescriptor(dataType.name, typeConstructor))
227 errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
228 dataType.typeConstructor = typeConstructor;
231 for(DTypeAst typeAlias : typeAliasesAst) {
232 TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
233 NameExistenceChecks.checkIfTypeExists(errorLog,
234 typeAlias.location, importedEnvironment, typeAlias.name);
235 if(module.addTypeDescriptor(typeAlias.name, alias)) {
236 errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
240 for(DEffectAst effect : effectsAst) {
241 EffectConstructor effectConstructor = new EffectConstructor(Types.con(moduleName, effect.name));
242 effectConstructor.addThreadLocalVariable(
243 new ThreadLocalVariable(
245 TypeDesc.forClass(effect.threadLocalType)
247 if(module.addEffectConstructor(effect.name, effectConstructor))
248 errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
250 javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment);
251 compilationContext.javaTypeTranslator = javaTypeTranslator;
254 private static final int[] EMPTY_INT_ARRAY = new int[0];
256 public void processTypeAliases(ArrayList<DTypeAst> typeAliasesAst) {
257 TObjectIntHashMap<String> typeAliasMap = new TObjectIntHashMap<String>();
258 for(int i=0;i<typeAliasesAst.size();++i)
259 typeAliasMap.put(typeAliasesAst.get(i).name, i);
260 TIntHashSet tempIntSet = new TIntHashSet();
261 ArrayList<DTypeAst> orderedTypeAliases = new ArrayList<DTypeAst>(typeAliasesAst.size());
262 //for(int i=0;i<typeAliasesAst.size();++i)
263 // System.out.println(i + "# " + typeAliasesAst.get(i).name);
264 new StronglyConnectedComponents(typeAliasesAst.size()) {
266 protected int[] findDependencies(int u) {
267 typeAliasesAst.get(u).type.collectReferences(typeAliasMap, tempIntSet);
268 if(tempIntSet.isEmpty())
269 return EMPTY_INT_ARRAY;
270 if(tempIntSet.contains(u)) {
271 errorLog.log(typeAliasesAst.get(u).location, "Type alias has a self reference.");
272 tempIntSet.remove(u);
274 int[] result = tempIntSet.toArray();
276 //System.out.println(u + " -> " + Arrays.toString(result));
280 protected void reportComponent(int[] component) {
281 //System.out.println("component: " + Arrays.toString(component));
282 if(component.length > 1) {
283 StringBuilder b = new StringBuilder();
284 b.append("Recursively defined type alias (");
285 long minLocation = typeAliasesAst.get(component[0]).location;
286 boolean first = true;
287 for(int u : component) {
288 DTypeAst typeAlias = typeAliasesAst.get(u);
293 b.append(typeAlias.name);
294 if(Locations.beginOf(typeAlias.location) < Locations.beginOf(minLocation))
295 minLocation = typeAlias.location;
298 errorLog.log(minLocation, b.toString());
301 orderedTypeAliases.add(typeAliasesAst.get(component[0]));
305 if(errorLog.hasNoErrors()) {
306 for(DTypeAst typeAlias : orderedTypeAliases) {
307 TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name);
308 TypeTranslationContext context = createTypeTranslationContext();
309 for(int i=0;i<typeAlias.parameters.length;++i)
310 context.pushTypeVar(typeAlias.parameters[i]);
311 alias.body = typeAlias.type.toType(context, Kinds.metaVar());
312 for(int i=0;i<typeAlias.parameters.length;++i)
313 alias.parameters[i] = context.popTypeVar(typeAlias.parameters[i], null);
318 public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
319 for(DDataAst dataTypeAst : dataTypesAst) {
320 TypeTranslationContext context = createTypeTranslationContext();
321 TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
322 for(int i=0;i<dataTypeAst.parameters.length;++i)
323 typeParameters[i] = context.addTypeVar(dataTypeAst.parameters[i]);
324 Constructor[] constructors = new Constructor[dataTypeAst.constructors.length];
325 String className = null;
326 boolean external = false;
327 for(DAnnotationAst annotation : dataTypeAst.getAnnotations()) {
328 if(annotation.id.text.equals("@JavaType")) {
329 if(annotation.parameters.length != 1 ||
330 !(annotation.parameters[0] instanceof ELiteral) ||
331 !(((ELiteral)annotation.parameters[0]).getValue() instanceof StringConstant))
332 errorLog.log(annotation.location, "Invalid parameters. Expected @JavaType \"className\".");
334 className = ((StringConstant)((ELiteral)annotation.parameters[0]).getValue()).getValue().replace('.', '/');
341 boolean trivialDataType = dataTypeAst.constructors.length == 1 &&
342 dataTypeAst.constructors[0].parameters.length == 1;
343 if(className == null && !trivialDataType)
344 className = compilationContext.namingPolicy.getDataTypeClassName(dataTypeAst.name);
346 StandardTypeConstructor dataType = dataTypeAst.typeConstructor;
348 dataType.setType(Types.con(moduleName, dataTypeAst.name), typeParameters);
349 dataType.setConstructors(constructors);
351 dataType.setTypeDesc(TypeDesc.forClass(className));
352 if(!external || dataTypeAst.constructors.length > 0) {
353 dataType.isOpen = false;
355 dataType.external = external;
356 dataTypes.add(dataType);
357 for(int j=0;j<constructors.length;++j) {
358 ConstructorAst constructor = dataTypeAst.constructors[j];
359 String name = constructor.name;
360 Type[] parameterTypes = new Type[constructor.parameters.length];
361 for(int i=constructor.parameters.length-1;i>=0;--i)
362 parameterTypes[i] = context.toType(constructor.parameters[i]);
363 String javaName = constructors.length == 1 ? className
364 : compilationContext.namingPolicy.getConstructorClassName(name);
365 String[] fieldNames = null;
366 for(DAnnotationAst annotation : constructor.annotations)
367 if(annotation.id.text.equals("@JavaType")) {
369 javaName = ((StringConstant)((ELiteral)annotation.parameters[0])
370 .getValue()).getValue();
371 } catch(Exception e) {
372 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
375 else if(annotation.id.text.equals("@FieldNames")) {
377 EListLiteral literal = (EListLiteral)annotation.parameters[0];
378 fieldNames = new String[literal.getComponents().length];
379 for(int i=0;i<fieldNames.length;++i) {
380 Expression component = literal.getComponents()[i];
381 if(component instanceof EVar)
382 fieldNames[i] = ((EVar)component).name;
383 else if(component instanceof ELiteral)
384 fieldNames[i] = ((StringConstant)((ELiteral)component).getValue()).getValue();
386 } catch(Exception e) {
387 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
392 constructors[j] = new Constructor(constructor.location, dataType,
393 Name.create(moduleName, name),
394 parameterTypes, javaName);
395 constructors[j].fieldNames = fieldNames;
396 constructors[j].recordFieldNames = constructor.fieldNames;
401 public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {
402 for(ProcessedDClassAst pClassAst : typeClassesAst) {
403 DClassAst classAst = pClassAst.orig;
405 if(module.getTypeClass(classAst.name) != null) {
406 errorLog.log(classAst.location, "Class "+classAst.name+" has already been defined in this module.");
410 TypeTranslationContext context = createTypeTranslationContext();
412 TPred[] classContext = new TPred[classAst.context.length];
413 for(int i=0;i<classContext.length;++i)
414 classContext[i] = context.toTFuncApply(classAst.context[i]);
416 TVar[] parameters = new TVar[classAst.parameters.length];
418 if(classAst.name.equals("Functor") || classAst.name.equals("Monad")) {
420 parameters[0] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[0], Kinds.STAR_TO_STAR);
423 for(int i=0;i<parameters.length;++i)
424 parameters[i] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[i], Kinds.metaVar());
427 TCon con = Types.con(moduleName, classAst.name);
428 TypeClass typeClass = new TypeClass(classAst.location,
431 compilationContext.namingPolicy.getTypeClassInterfaceName(con),
433 Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
435 THashMap<String, TypeClassMethod> methods = typeClass.methods;
436 for(DValueTypeAst methodDecl : pClassAst.typeDeclarations) {
440 type = context.toType(methodDecl.type);
441 } catch(SCLSyntaxErrorException e) {
442 errorLog.log(e.location, e.getMessage());
445 for(EVar name : methodDecl.names) {
446 typeClass.methodNames.add(name.name);
447 methods.put(name.name,
448 new TypeClassMethod(typeClass, name.name,
449 compilationContext.namingPolicy.getMethodName(name.name),
450 type, Types.getArity(type),
454 } catch(RuntimeException e) {
455 errorLog.setExceptionPosition(methodDecl.location);
460 for(String methodName : pClassAst.defaultImplementations.getValueNames()) {
461 String fullName = "_" + classAst.name + "_default_" + methodName;
462 ArrayList<DValueAst> defs = pClassAst.defaultImplementations.getDefinition(methodName);
464 TypeClassMethod method = typeClass.methods.get(methodName);
466 errorLog.log(defs.get(0).location, "Method " + methodName + " is not defined in this class.");
469 method.setDefaultImplementation(Name.create(moduleName, fullName));
471 valueDefinitionsAst.addDefinitions(fullName, defs);
472 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
473 Collections.<Expression>emptyList()));*/
474 supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType()));
477 module.addTypeClass(classAst.name, typeClass);
481 private TypeTranslationContext createTypeTranslationContext() {
482 return new TypeTranslationContext(compilationContext);
485 public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
486 ArrayList<ProcessedDInstanceAst> instancesAst) {
487 for(DDerivingInstanceAst derivingInstance : derivingInstancesAst) {
488 String name = derivingInstance.name.name;
491 con = Environments.getTypeClassName(compilationContext.environment, name);
492 } catch (AmbiguousNameException e) {
493 errorLog.log(derivingInstance.name.location, e.getMessage());
497 errorLog.log(derivingInstance.name.location, "Couldn't resolve class " + name + ".");
500 InstanceDeriver deriver = InstanceDerivers.get(con);
502 errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + ".");
504 deriver.derive(errorLog, compilationContext.environment, instancesAst, derivingInstance);
508 public void processInstances(ArrayList<ProcessedDInstanceAst> instancesAst) {
509 THashSet<TPred> instanceClashCheckSet = new THashSet<TPred>();
510 for(ProcessedDInstanceAst pInstanceAst : instancesAst) {
511 DInstanceAst instanceAst = pInstanceAst.orig;
513 TypeTranslationContext context = createTypeTranslationContext();
515 String name = instanceAst.name.name;
518 typeClassCon = Environments.getTypeClassName(compilationContext.environment, name);
519 } catch (AmbiguousNameException e) {
520 errorLog.log(instanceAst.name.location, e.getMessage());
523 if(typeClassCon == null) {
524 errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + ".");
527 TypeClass typeClass = compilationContext.environment.getTypeClass(typeClassCon);
528 pInstanceAst.typeClass = typeClass;
530 if(instanceAst.types.length != typeClass.parameters.length) {
531 errorLog.log(instanceAst.location, "Wrong number of parameters to type class " + typeClassCon.name + ".");
534 Type[] parameters = new Type[instanceAst.types.length];
535 for(int i=0;i<parameters.length;++i)
536 parameters[i] = context.toType(instanceAst.types[i], typeClass.parameters[i].getKind() /* FIXME */);
537 TPred instance = Types.pred(typeClassCon, parameters);
539 if(!instanceClashCheckSet.add(instance)) {
540 errorLog.log(instanceAst.location, "Duplicate definition of the instance " + instance + ".");
544 TPred[] instanceContext = new TPred[instanceAst.context.length];
545 for(int i=0;i<instanceContext.length;++i)
546 instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
548 String javaName = compilationContext.namingPolicy.getInstanceClassName(instance);
549 String instancePrefix = instance.toName() + "$";
551 ValueRepository valueDefs = pInstanceAst.valueDefs;
553 THashMap<String, MethodImplementation> methodImplementations =
554 new THashMap<String, MethodImplementation>();
555 for(String valueName : valueDefs.getValueNames()) {
556 String fullName = instancePrefix + valueName;
557 long loc = valueDefs.getDefinition(valueName).get(0).location;
558 valueDefinitionsAst.addFrom(valueDefs, valueName, fullName);
559 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
560 Collections.<Expression>emptyList()));*/
561 TypeClassMethod method = typeClass.methods.get(valueName);
563 errorLog.log(loc, "Method " + valueName + " is not defined in the type class " + typeClass.name.name + ".");
566 Type type = method.getBaseType().replace(typeClass.parameters, parameters);
567 for(int i=instanceContext.length-1;i>=0;--i)
568 type = Types.constrained(instanceContext[i], type);
569 //System.out.println(valueName + " :: " + type);
570 supplementedTypeAnnotations.add(
571 new SupplementedValueType(loc, fullName, type));
572 methodImplementations.put(valueName,
573 new MethodImplementation(Name.create(moduleName, fullName), false));
576 // Are all necessary methods defined
577 for(String methodName : typeClass.methods.keySet())
578 if(!methodImplementations.containsKey(methodName)) {
579 Name defaultImplementation = typeClass.methods.get(methodName).getDefaultImplementation();
580 if(defaultImplementation == null)
581 errorLog.log(instanceAst.location, "Method " + methodName + " is not defined.");
583 methodImplementations.put(methodName,
584 new MethodImplementation(defaultImplementation, true));
587 JavaTypeInstanceConstructor generator = new JavaTypeInstanceConstructor(javaName, instance, instanceContext);
588 if(instanceContext.length == 0)
589 generator.setHasStaticInstance(true);
591 TypeClassInstance typeClassInstance =
592 new TypeClassInstance(instanceAst.location, typeClass, generator,
593 generator.getTypeParameters(),
594 instanceContext, instance, methodImplementations,
597 generator.setInstance(typeClassInstance);
599 module.addTypeClassInstance(typeClassCon, typeClassInstance);
600 } catch(RuntimeException e) {
601 errorLog.setExceptionPosition(instanceAst.location);
606 // Generate superclass functions
607 for(ArrayList<TypeClassInstance> instanceArray : module.getTypeInstances().values())
608 for(TypeClassInstance instance : instanceArray) {
610 TypeClass typeClass = instance.typeClass;
611 int superCount = typeClass.context.length;
613 instance.superExpressions = new SCLValue[superCount];
614 for(int i=0;i<superCount;++i) {
615 TPred type = (TPred)typeClass.context[i]
616 .replace(typeClass.parameters, instance.instance.parameters);
617 SCLValue value = new SCLValue(Name.create(moduleName,
618 instance.javaName.substring(instance.javaName.indexOf('$')+1) + "_super" + i));
619 //value.addProperty(PrivateProperty.INSTANCE);
620 module.addValue(value);
621 Expression expression = new EGetConstraint(instance.location, type);
622 value.setExpression(expression);
623 value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type)));
624 value.getProperties().add(new InlineProperty(instance.context.length, 0xffffffff));
625 //TypeUnparsingContext tuc = new TypeUnparsingContext();
626 // TODO error handling
627 instance.superExpressions[i] = value;
629 } catch(RuntimeException e) {
630 errorLog.setExceptionPosition(instance.getLocation());
636 public void processJavaMethods(ArrayList<JavaMethodDeclaration> javaMethodDeclarations) {
637 for(JavaMethodDeclaration javaMethod : javaMethodDeclarations) {
638 String name = javaMethod.methodName.name;
639 String javaName = name;
640 ArrayList<DAnnotationAst> annotations =
641 valueDefinitionsAst.getAnnotations(name);
642 boolean isPrivate = false;
643 if(annotations != null) {
644 for(DAnnotationAst annotation : annotations)
645 if(annotation.id.text.equals("@JavaName")) {
646 String temp = AnnotationUtils.processStringAnnotation(errorLog, annotation);
650 else if(annotation.id.text.equals("@private")) {
651 AnnotationUtils.processTagAnnotation(errorLog, annotation);
656 Type type = createTypeTranslationContext().toType(javaMethod.type);
658 CallJava callJava = resolveMethod(
660 javaMethod.className,
663 if(callJava != null) {
664 NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location,
665 importedEnvironment, name);
666 SCLValue value = module.addValue(name, callJava);
667 value.definitionLocation = javaMethod.methodName.location;
669 value.addProperty(PrivateProperty.INSTANCE);
675 * Convert a java class method into a {@link CallJava} instance.
676 * Compilation errors are logged for failures in finding the named class or in accessing the method.
677 * The return value for errors is {@code null}.
679 * @param loc SCL source location
680 * @param className Name of the class
681 * @param methodName Name of the method
682 * @param type The expected SCL type of the method
683 * @return A new JavaCall instance, or null if the given method can not be instantiated.
685 private CallJava resolveMethod(long loc,
686 String className, String methodName, Type type) {
688 ClassRef classRef = classRefs.get(className);
689 if(classRef == null) {
690 if(classRefs.containsKey(className))
692 classRef = javaReferenceValidator.getClassRef(className);
693 classRefs.put(className, classRef);
694 if(classRef == null) {
695 errorLog.log(loc, "Didn't find class " + className + ".");
698 if(!javaReferenceValidator.isPublic(classRef.getClass())) {
699 errorLog.log(loc, "Class " + className + " is not public.");
706 List<MethodRef> methodRefs = classRef.getMethodRefs(methodName);
707 if(methodRefs.isEmpty()) {
708 errorLog.log(loc, "Didn't find any public method or field with name '" + methodName + "' from class " + className + ".");
712 ArrayList<CallJava> candidates = new ArrayList<CallJava>(2);
713 for(MethodRef methodRef : methodRefs) {
714 CallJava candidate = matchType(methodRef, type);
715 if(candidate != null)
716 candidates.add(candidate);
719 if(candidates.isEmpty()) {
720 StringBuilder b = new StringBuilder();
721 b.append("Didn't find any public method or field matching the type " + type + ". The following methods and fields were tried:");
722 for(MethodRef methodRef : methodRefs) {
726 b.append("\nbut expected something like:");
728 MultiFunction mFun = Types.matchFunction(type);
729 b.append("\n public static ");
730 b.append(javaTypeTranslator.toTypeDesc(mFun.returnType).getFullName()).append(' ').append(methodName).append('(');
731 boolean first = true;
732 for(Type parameter : mFun.parameterTypes) {
737 b.append(javaTypeTranslator.toTypeDesc(parameter).getFullName());
741 errorLog.log(loc, b.toString());
744 else if(candidates.size() == 1)
745 return candidates.get(0);
747 // Try to find the best match
748 ArrayList<CallJava> bestCandidates = new ArrayList<CallJava>(candidates.size());
749 loop: for(CallJava candidate : candidates) {
750 Iterator<CallJava> it = bestCandidates.iterator();
751 while(it.hasNext()) {
752 CallJava b = it.next();
753 switch(candidate.compareTo(javaReferenceValidator, b)) {
757 case CallJava.GREATER:
760 case CallJava.INCOMPARABLE:
764 bestCandidates.add(candidate);
767 if(bestCandidates.size() == 1) {
768 // System.out.println("Choose: " + bestCandidates.get(0).getMethodRef());
769 return bestCandidates.get(0);
772 StringBuilder b = new StringBuilder();
773 b.append("Found more than one incomparable public methods the type " + type + ":");
774 for(CallJava callJava : bestCandidates) {
776 b.append(callJava.getMethodRef());
778 errorLog.log(loc, b.toString());
784 private CallJava matchType(MethodRef methodRef, Type type) {
785 //System.out.println("-----------------------------------------------------");
786 //System.out.println("method: " + methodRef);
787 //System.out.println("type: " + type);
789 type = Types.canonical(type);
790 while(type instanceof TForAll)
791 type = Types.canonical(((TForAll)type).type);
793 TypeDesc[] expectedParameterTypes = methodRef.getParameterTypes();
795 ArrayList<Type> parameterTypes = new ArrayList<Type>();
796 Type effect = Types.NO_EFFECTS;
797 Type returnType = type;
799 StackItem[] stackItems = new StackItem[expectedParameterTypes.length];
800 TIntArrayList unresolvedItems = new TIntArrayList();
803 for(int i=0;i<expectedParameterTypes.length;++i) {
805 TypeDesc providedParameterType;
807 if(effect != Types.NO_EFFECTS || !(returnType instanceof TFun)) {
808 while(i < expectedParameterTypes.length)
809 unresolvedItems.add(i++);
812 TFun fun = (TFun)returnType;
813 parameterType = Types.canonical(fun.domain);
814 parameterTypes.add(parameterType);
815 effect = Types.canonical(fun.effect);
816 returnType = Types.canonical(fun.range);
817 providedParameterType = javaTypeTranslator.toTypeDesc(parameterType);
818 } while(providedParameterType.equals(TypeDesc.VOID));
821 TypeDesc expectedParameterType = expectedParameterTypes[i];
822 if(javaReferenceValidator.isAssignableFrom(expectedParameterType,
823 providedParameterType)) {
824 stackItems[i] = new ParameterStackItem(
825 parameterTypes.size()-1,
830 unresolvedItems.add(i++);
831 if(i == expectedParameterTypes.length) {
832 parameterTypes.remove(parameterTypes.size()-1);
833 returnType = Types.functionE(parameterType, effect, returnType);
838 //System.out.println("returnType: " + returnType);
839 if(!unresolvedItems.isEmpty()) {
840 ArrayList<TCon> concreteEffects = new ArrayList<TCon>();
841 effect.collectConcreteEffects(concreteEffects);
843 for(TCon eff : concreteEffects) {
844 EffectConstructor effC = compilationContext.environment.getEffectConstructor(eff);
845 for(ThreadLocalVariable var : effC.getThreadLocalVariables()) {
846 for(int i=0;i<unresolvedItems.size();++i) {
847 int id = unresolvedItems.get(i);
848 if(!expectedParameterTypes[id].equals(TypeDesc.OBJECT) &&
849 javaReferenceValidator.isAssignableFrom(expectedParameterTypes[id], var.type)) {
850 stackItems[id] = new ThreadLocalStackItem(var.variableName, var.type);
851 unresolvedItems.removeAt(i);
858 if(!unresolvedItems.isEmpty())
860 /*System.out.print("Unresolved: ");
861 boolean first = true;
862 for(int i=0;i<unresolvedItems.size();++i) {
866 System.out.print(", ");
867 System.out.print(expectedParameterTypes[unresolvedItems.get(i)]);
869 System.out.println();*/
871 OutputFilter filter = null;
873 TypeDesc providedReturnType = methodRef.getReturnType();
874 if(!providedReturnType.equals(Constants.FUNCTION)) {
875 while(returnType instanceof TFun && effect == Types.NO_EFFECTS) {
876 TFun fun = (TFun)returnType;
877 Type parameterType = Types.canonical(fun.domain);
878 if(!javaTypeTranslator.toTypeDesc(parameterType).equals(TypeDesc.VOID))
880 parameterTypes.add(parameterType);
881 effect = Types.canonical(fun.effect);
882 returnType = Types.canonical(fun.range);
885 TypeDesc expectedReturnType =
886 javaTypeTranslator.toTypeDesc(returnType);
887 if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
888 providedReturnType)) {
889 if(expectedReturnType.equals(TypeDesc.VOID)) {
890 if(providedReturnType.equals(TypeDesc.DOUBLE) || providedReturnType.equals(TypeDesc.LONG))
891 filter = Pop2OutputFilter.INSTANCE;
893 filter = PopOutputFilter.INSTANCE;
895 else if(expectedReturnType.equals(Constants.LIST)
896 && providedReturnType.equals(Constants.COLLECTION))
897 filter = ConvertToListFilter.INSTANCE;
903 CallJava result = new CallJava(
904 Types.freeVarsArray(type),
907 parameterTypes.toArray(new Type[parameterTypes.size()]),
911 //System.out.println(result.getType());
915 public void processMappingRelations(ArrayList<DMappingRelationAst> mappingRelationsAst) {
916 for(DMappingRelationAst mappingRelation : mappingRelationsAst) {
917 TypeAst[] parameterTypesAst = mappingRelation.parameterTypes;
918 Type[] parameterTypes = new Type[parameterTypesAst.length];
919 TypeTranslationContext typeTranslationContext = createTypeTranslationContext();
920 for(int i=0;i<parameterTypes.length;++i)
921 parameterTypes[i] = parameterTypesAst[i].toType(typeTranslationContext, Kinds.STAR);
922 MappingRelation mRel =
923 new MappingRelation(Name.create(moduleName, mappingRelation.name), parameterTypes);
924 mRel.location = mappingRelation.location;
925 if(module.addMappingRelation(mRel))
926 errorLog.log(mappingRelation.location, "Mapping relation " + mappingRelation.name +
927 " has already been defined.");
931 THashMap<String, DRuleAst> ruleAstMap = new THashMap<String, DRuleAst>();
933 public void processRules(ArrayList<DRuleAst> rulesAst) {
934 // Find implied mapping relations
935 for(DRuleAst ruleA : rulesAst) {
936 ArrayList<Query> whereSection = ruleA.getSections().get("where");
937 if(whereSection != null)
938 for(Query query : whereSection) {
939 if(!(query instanceof QPreGuard))
941 QPreGuard guard = (QPreGuard)query;
942 if(!(guard.guard instanceof EApply))
944 EApply apply = (EApply)guard.guard;
945 if(!(apply.getFunction() instanceof EVar))
948 String name = ((EVar)apply.getFunction()).name;
949 if(module.getMappingRelation(name) != null)
952 int arity = apply.getParameters().length;
953 Type[] parameterTypes = new Type[arity];
954 for(int i=0;i<arity;++i)
955 parameterTypes[i] = Types.metaVar(Kinds.STAR);
956 MappingRelation mRel =
957 new MappingRelation(Name.create(moduleName, name), parameterTypes);
958 mRel.location = query.location;
959 module.addMappingRelation(mRel);
961 if(ruleAstMap.put(ruleA.name, ruleA) != null)
962 errorLog.log(ruleA.location, "Rule " + ruleA.name +
963 " has already been defined.");
967 for(String ruleName : ruleAstMap.keySet())
968 processRule(ruleName);
971 private TransformationRule processRule(String ruleName) {
972 TransformationRule rule = module.getRule(ruleName);
976 DRuleAst ruleAst = ruleAstMap.get(ruleName);
977 if(ruleAst.alreadyProcessing) {
978 errorLog.log(ruleAst.location, "Cyclic chain of rule extensions.");
982 TransformationRule[] extendsRules;
983 int length = ruleAst.extendsNames.length;
985 extendsRules = TransformationRule.EMPTY_ARRAY;
987 extendsRules = new TransformationRule[length];
988 for(int i=0;i<length;++i) {
990 String extendsName = ruleAst.extendsNames[i];
991 TransformationRule extendsRule;
992 if(ruleAstMap.containsKey(extendsName))
993 extendsRule = processRule(extendsName);
995 extendsRule = Environments.getRule(compilationContext.environment, extendsName);
996 if(extendsRule == null)
997 errorLog.log(ruleAst.location,
998 "Couldn't resolve rule name " + extendsName + ".");
1000 extendsRules[i] = extendsRule;
1001 } catch(AmbiguousNameException e) {
1002 errorLog.log(ruleAst.location, e.getMessage());
1007 final THashMap<SectionName, Query[]> sections = new THashMap<SectionName, Query[]>();
1009 final TranslationContext context = createTranslationContext();
1011 THashMap<String, Variable> variables = context.getVariables();
1012 for(TransformationRule extendsRule : extendsRules) {
1013 if(extendsRule == null)
1015 for(Variable var : extendsRule.variables)
1016 if(variables.put(var.getName(), var) != null) {
1017 errorLog.log(ruleAst.location,
1018 "Variable " + var.getName() + " is defined in more than one base rule, which is not currently allowed.");
1022 context.pushExistentialFrame();
1023 ruleAst.getSections().forEachEntry(new TObjectObjectProcedure<String, ArrayList<Query>>() {
1025 public boolean execute(String sectionNameString, ArrayList<Query> queries) {
1026 Query[] resolvedQueries = new Query[queries.size()];
1027 for(int i=0;i<resolvedQueries.length;++i)
1028 resolvedQueries[i] = queries.get(i).resolve(context);
1030 SectionName sectionName = SectionName.getSectionName(sectionNameString);
1031 if(sectionName == null)
1032 context.getErrorLog().log(queries.get(0).location,
1033 "Invalid section name " + sectionNameString + ".");
1035 sections.put(sectionName, resolvedQueries);
1040 Variable[] variables = context.getVariables().values().toArray(new Variable[context.getVariables().size()]);
1042 rule = new TransformationRule(ruleAst.isAbstract,
1043 Name.create(moduleName, ruleAst.name),
1045 sections, variables);
1046 rule.location = ruleAst.location;
1047 module.addRule(rule);
1051 public void addDataTypesToEnvironment() {
1052 for(StandardTypeConstructor dataType : dataTypes) {
1053 int constructorTag = 0;
1054 for(Constructor constructor : dataType.constructors) {
1055 SCLValue value = new SCLValue(constructor.name);
1056 SCLConstructor sclConstructor =
1058 constructor.name.name,
1059 constructor.javaName,
1060 constructor.getTypeVariables(),
1062 constructor.getReturnType(),
1063 constructor.fieldNames == null
1064 ? SCLConstructor.DEFAULT_FIELD_NAMES[constructor.getParameterTypes().length]
1065 : constructor.fieldNames,
1066 constructor.recordFieldNames,
1067 constructor.getParameterTypes());
1068 if(dataType.constructors.length == 1 && (
1069 dataType.getTypeDesc() == null ||
1070 dataType.constructors[0].javaName.equals(MethodBuilderBase.getClassName(dataType.getTypeDesc()))))
1071 sclConstructor.setOnlyConstructor(true);
1072 value.setValue(sclConstructor);
1073 value.setType(constructor.getType());
1075 NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc,
1076 importedEnvironment, constructor.name.name);
1077 if(module.addValue(value)) {
1078 errorLog.log(constructor.loc,
1079 "Value " + constructor.name.name + " is already defined.");
1085 public void addTypeClassesToEnvironment() {
1086 for(TypeClass typeClass : module.getTypeClasses()) {
1087 for(TypeClassMethod method : typeClass.methods.values()) {
1088 SCLValue value = method.createValue();
1089 value.definitionLocation = method.location;
1090 NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION,
1091 importedEnvironment, value.getName().name);
1093 if(module.addValue(value)) {
1094 String name = method.getName();
1095 long location = Locations.NO_LOCATION;
1096 ArrayList<DValueAst> definitions = valueDefinitionsAst.getDefinition(name);
1097 if(definitions != null && !definitions.isEmpty())
1098 location = definitions.get(0).location;
1099 errorLog.log(location, "Value " + name + " is already defined.");
1105 public void preprocessValueDefinitions(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1106 for(String name : valueDefinitionsAst.getValueNames()) {
1107 SCLValue value = new SCLValue(Name.create(moduleName, name));
1109 long location = valueDefinitionsAst.getLocation(name);
1110 NameExistenceChecks.checkIfValueExists(errorLog, location,
1111 importedEnvironment, value.getName().name);
1112 value.definitionLocation = location;
1113 if(module.addValue(value))
1114 errorLog.log(location, "Value " + name + " is already defined.");
1116 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1117 for(EVar name : valueTypeAst.names) {
1118 SCLValue value = module.getValue(name.name);
1120 errorLog.log(valueTypeAst.location, name.name + " is not defined.");
1121 value = new SCLValue(Name.create(moduleName, name.name));
1122 module.addValue(value);
1124 value.definitionLocation = name.location;
1126 for(String name : relationDefinitionsAst.getRelationNames()) {
1127 ConcreteRelation relation = new ConcreteRelation(name);
1128 module.addRelation(name, relation);
1132 public void addValueDefinitionsToEnvironment(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1133 THashMap<String, DValueTypeAst> typeMap = new THashMap<String, DValueTypeAst>();
1134 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1135 for(EVar name : valueTypeAst.names) {
1136 if(typeMap.containsKey(name.name))
1137 errorLog.log(valueTypeAst.location, "Type of "+name.name+" has already been declared in this module.");
1139 typeMap.put(name.name, valueTypeAst);
1142 for(String name : valueDefinitionsAst.getValueNames()) {
1143 ArrayList<DValueAst> defs = valueDefinitionsAst.getDefinition(name);
1145 SCLValue value = module.getValue(name);
1146 TranslationContext context = createTranslationContext();
1147 Expression expression = context.translateCases2(defs);
1148 value.setExpression(expression);
1150 DValueTypeAst valueTypeAst = typeMap.remove(name);
1151 if(valueTypeAst != null)
1152 value.setType(Types.closure(context.toType(valueTypeAst.type)));
1154 ArrayList<DAnnotationAst> annotations = valueDefinitionsAst.getAnnotations(name);
1155 if(annotations != null)
1156 for(DAnnotationAst annotation : annotations) {
1157 handleAnnotation(value, defs, annotation);
1159 } catch(RuntimeException e) {
1160 errorLog.setExceptionPosition(defs.get(0).location);
1164 for(String name : relationDefinitionsAst.getRelationNames()) {
1165 ArrayList<DRelationAst> definitions = relationDefinitionsAst.getDefinition(name);
1166 if(definitions.size() > 1) {
1167 errorLog.log(definitions.get(1).location,
1168 "Does not yet support definition of relations by more than one rule.");
1172 DRelationAst definition = definitions.get(0);
1173 ConcreteRelation relation = (ConcreteRelation)module.getRelation(name);
1174 relation.location = definition.location;
1175 TranslationContext context = createTranslationContext();
1176 definition.translateTo(context, relation);
1180 private TranslationContext createTranslationContext() {
1181 return new TranslationContext(compilationContext, null);
1184 private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
1185 if(annotation.id.text.equals("@macro")) {
1186 value.setMacroRule(new StandardMacroRule());
1188 else if(annotation.id.text.equals("@inline")) {
1190 int arity = defs.get(0).lhs.getFunctionDefinitionPatternArity();
1191 int phaseMask = 0xffffffff;
1192 if(annotation.parameters.length > 0) {
1193 phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
1195 value.addProperty(new InlineProperty(arity, phaseMask));
1196 } catch(NotPatternException e) {
1197 errorLog.log(annotation.location, "Inline annotation is invalid: this is not a function.");
1200 else if(annotation.id.text.equals("@private")) {
1201 value.addProperty(PrivateProperty.INSTANCE);
1203 else if(annotation.id.text.equals("@deprecated")) {
1204 String description = "";
1205 if(annotation.parameters.length > 0) {
1206 if(annotation.parameters.length > 1)
1207 errorLog.log(annotation.location, "Invalid number of parameters, expected one string.");
1209 String temp = AnnotationUtils.extractString(annotation.parameters[0]);
1211 errorLog.log(annotation.location, "Invalid parameter, expected one string.");
1216 value.addProperty(new DeprecatedProperty(description));
1219 errorLog.log(annotation.location, "Unknown annotation.");
1222 public void addSupplementedTypeAnnotationsToEnvironment() {
1223 for(SupplementedValueType valueType : supplementedTypeAnnotations) {
1224 Type type = Types.closure(valueType.type);
1225 String name = valueType.name;
1226 SCLValue value = module.getValue(name);
1228 errorLog.log(valueType.position,
1229 name + " is not defined.");
1230 else if(value.getType()==null)
1231 value.setType(type);
1233 errorLog.log(valueType.position,
1234 "Type of "+name+" has already been declared in this module.");
1238 public void addFixityToEnvironment(ArrayList<DFixityAst> fixityAst) {
1239 for(DFixityAst fixity : fixityAst) {
1240 for(EVar symbol : fixity.symbols) {
1241 String name = symbol.name;
1242 SCLValue value = module.getValue(name);
1244 errorLog.log(symbol.location,
1245 name + " is not defined.");
1247 value.setPrecedence(fixity.precedence);
1252 public void addCoverageBranchPoints() {
1253 branchPoints = new THashMap<String, BranchPoint[]>();
1254 BranchPointInjector injector = new BranchPointInjector();
1255 for(String valueName : valueDefinitionsAst.getValueNames()) {
1256 for(DValueAst valueAst : valueDefinitionsAst.getDefinition(valueName))
1257 valueAst.value = injector.injectBranchPoint(valueAst.value);
1258 branchPoints.put(valueName, injector.getAndClearBranchPoints());