source: branches/dev-mj-1626/Compiler/ModelicaFrontEnd/src/jastadd/instance/InstTypeAnalysis.jrag @ 13095

Last change on this file since 13095 was 13095, checked in by tgutzmann, 5 months ago

Merge from trunk

File size: 30.2 KB
Line 
1/*
2    Copyright (C) 2014 Modelon AB
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, version 3 of the License.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17import java.util.ArrayList;
18import java.util.Arrays;
19import java.util.Collection;
20import java.util.Collections;
21import java.util.TreeSet;
22import java.util.Set;
23import java.util.HashSet;
24
25
26aspect InstTypeAnalysis {
27
28    syn FType InstComponentModification.type() {
29        if (getName().myInstComponentDecl().isAssignable()) {
30            InstAssignable ip = ((InstAssignable)getName().myInstComponentDecl());
31            return ip.type();
32        } else {
33            return fUnknownType();
34        }
35    }
36
37    syn lazy FType InstAssignable.type();
38
39    eq InstPrimitive.type() {
40        FType scalar = primitiveScalarType();
41        return isArray() ? scalar.arrayType(size()) : scalar;
42    }
43    eq InstExternalObject.type() = getType();
44
45    /**
46     * The scalar type of this class or component, if it is a primitive type, otherwise the unknown type.
47     */
48    syn FType InstNode.primitiveScalarType() {
49        if (isReal()) 
50            return fRealScalarType();
51        else if (isInteger()) 
52            return fIntegerScalarType();
53        else if (isBoolean()) 
54            return fBooleanScalarType();
55        else if (isString()) 
56            return fStringScalarType();
57        else if (isExternalObject())
58            return new FExternalObjectType(Size.SCALAR, "ExternalObject", new FAccessString("ExternalObject.constructor"), new FAccessString("ExternalObject.destructor"));
59        return fUnknownType();
60    }
61
62    eq InstClassDecl.primitiveScalarType()          = isEnum() ? enumType() : super.primitiveScalarType();
63    eq InstEnum.primitiveScalarType()               = myInstClass().primitiveScalarType();
64    eq InstReplacingPrimitive.primitiveScalarType() = myInstClass().primitiveScalarType();
65    eq InstExternalObject.primitiveScalarType()     = myInstClass().enumType();
66    eq InstForIndexPrimitive.primitiveScalarType()  = myInstForIndexType();
67
68    inh FType InstForIndexPrimitive.myInstForIndexType();
69    eq InstForIndexWithExp.getInstPrimitive().myInstForIndexType() = getFExp().type().scalarType();
70    eq InstForIndexNoExp.getInstPrimitive().myInstForIndexType()   = hasFExp() ? 
71            getFExp().type().scalarType() : fUnknownType();
72    eq InstNode.getChild().myInstForIndexType()                  = fUnknownType();
73
74    syn nta FType InstExternalObject.getType() {
75        InstAccess con = InstAccess.fromName(myConstructor().qualifiedName());
76        InstAccess de  = InstAccess.fromName(myDestructor().qualifiedName());
77        return new FExternalObjectType(size(), getClassName().myInstClassDecl().qualifiedName(), con, de);
78    }
79
80
81    eq InstRecord.type()  = createRecordType();
82
83    syn FType InstComponentDecl.createRecordType() {
84        InstComponentDecl root = this;
85        for (int i = 0; i < ndims(); i++) {
86            if (root.getNumInstComponentDecl() == 0)
87                return myInstClass().recordType().sizedType(size());
88            root = root.getInstComponentDecl(0);
89        }
90        FRecordType type = myInstClass().resolveLib().createEmptyFRecordType(size());
91        for (InstComponentDecl icd : root.allInstComponentDecls()) 
92            type.addComponent(new FRecordComponentType(icd.name(), (FType) icd.type().treeCopy()));
93        return type;
94    }
95
96    syn nta lazy FRecordType InstClassDecl.recordType() {
97        FRecordType type = resolveLib().createEmptyFRecordType(Size.SCALAR);
98        for (InstComponentDecl icd : allInstComponentDecls()) 
99            type.addComponent(new FRecordComponentType(icd.name(), (FType) icd.type().treeCopy()));
100        return type;
101    }
102
103    syn FRecordType InstClassDecl.createEmptyFRecordType(Size s) = null;
104    eq InstBaseClassDecl.createEmptyFRecordType(Size s)          = 
105        getInstRestriction().createEmptyFRecordType(s);
106
107    syn FRecordType InstRestriction.createEmptyFRecordType(Size s) = null;
108    eq InstMRecord.createEmptyFRecordType(Size s)                  = 
109        new FRecordType(s, myInstClassDecl().qualifiedName(), new List(), null);
110    eq InstOperatorRecord.createEmptyFRecordType(Size s)           = 
111        new FOperatorRecordType(s, myInstClassDecl().baseClassName(), new List(), null, operatorMap());
112    eq InstConnector.createEmptyFRecordType(Size s)                = 
113        (inheritedRestriction() != null) ? inheritedRestriction().createEmptyFRecordType(s) : super.createEmptyFRecordType(s);
114
115
116    eq InstEnum.type()        = myInstClass().enumType().sizedType(size());
117    eq InstEnumLiteral.type() = myInstEnumClassDecl().enumType();
118
119    syn FType InstClassDecl.enumType() {
120        FEnumType type = new FEnumType(Size.SCALAR, qualifiedName(), new List());
121        for (InstEnumLiteral el : enumLiterals()) 
122            type.addFEnumLiteralType(new FEnumLiteralType(Size.SCALAR, el.name()));
123        return type;
124    }
125
126    eq InstPartialFunction.type() = functionType().sizedType(size());
127   
128    public interface InstCallable{
129        public FType functionType();
130    }
131   
132    syn FFunctionType InstClassDecl.functionType()       = getFunctionType();
133    syn FFunctionType InstPartialFunction.functionType() = myInstClass().functionType();
134   
135    syn FFunctionType InstClassDecl.getFunctionType() {
136        List<FRecordComponentType> inputTypes = new List();
137        List<FRecordComponentType> outputTypes = new List();
138        for (InstComponentDecl icd : myInputs())
139            inputTypes.add(new FRecordComponentType(icd.name(), icd.type().treeCopy()));
140        for (InstComponentDecl icd : myOutputs())
141            outputTypes.add(new FRecordComponentType(icd.name(), icd.type().treeCopy()));
142        return new FFunctionType(Size.SCALAR, actualInstClass().qualifiedName(), inputTypes, outputTypes, null);
143    }
144   
145    eq InstRecordConstructor.type() = getType();
146
147    syn FType InstRecordConstructor.getType() = getRecord().recordType().forConstructor(getArgs());
148
149    public FType FType.componentType(String name) {
150        return fUnknownType();
151    }
152   
153    public FType FRecordType.componentType(String name) {
154        FType res = componentType(name, getComponents());
155        return res == null ? super.componentType(name) : res;
156    }
157   
158    syn FRecordType InstAccess.recordType() = myInstClassDecl().recordType();
159
160    syn lazy FType InstComponentDecl.type() = fUnknownType();
161
162    eq InstArrayComponentDecl.type() {
163        return createRecordType();
164    }
165
166    eq InstFunctionCall.type() = hasOutputs() ? typeOfOutput(0) : fUnknownType();
167   
168    syn FFunctionType InstFunctionCall.declType() = myInstCallable().actualInstClassDecl().functionType();
169   
170    syn lazy FType InstFunctionCall.getFType() = declType().treeCopy().removeInputs().createSizeFExp(this);
171    eq InstVectorFunctionCall.getFType()       = declType().treeCopy().removeInputs().createSizeFExp(this).sizedType(vectorizedSize());
172    eq InstPartialFunctionCall.getFType() {
173        FFunctionType type = declType().treeCopy();
174        Set<String> s = new HashSet(namedArgs());
175        List<FRecordComponentType> n = new List<FRecordComponentType>();
176        for (FRecordComponentType frc : type.getInputs()) {
177            if (!s.contains(frc.getName())) {
178                n.add(frc);
179            }
180        }
181        type.setInputList(n);
182        return type;
183    }
184   
185    syn ArrayList<String> InstPartialFunctionCall.namedArgs() {
186        ArrayList<String> res = new ArrayList<String>();
187        for (InstComponentDecl icd : myInputsToBind(myInstCallable()))
188            res.add(icd.name());
189        return res;
190    }
191   
192    /**
193     * Remove input types
194     * @return this
195     */
196    public FFunctionType FFunctionType.removeInputs() {
197        setInputList(new List<FRecordComponentType>());
198        return this;
199    }
200   
201    syn boolean InstNode.isReal()            = false;
202    syn boolean InstNode.isInteger()         = false;
203    syn boolean InstNode.isBoolean()         = false;
204    syn boolean InstNode.isString()          = false;
205    syn boolean InstNode.isEnum()            = false;
206    syn boolean InstNode.isExternalObject()  = false;
207    syn boolean InstNode.isPartialFunction() = false;
208   
209    eq InstPrimitive.isReal()           = myInstClass().isReal();
210    eq InstPrimitive.isInteger()        = myInstClass().isInteger();
211    eq InstPrimitive.isBoolean()        = myInstClass().isBoolean();
212    eq InstPrimitive.isString()         = myInstClass().isString();
213    eq InstPrimitive.isEnum()           = myInstClass().isEnum();
214    eq InstEnum.isEnum()                = true;
215    eq InstExternalObject.isExternalObject() = true;
216    eq InstPartialFunction.isPartialFunction() = true;
217   
218    eq InstClassDecl.isReal()    = finalClass().primitiveName().equals("Real");
219    eq InstClassDecl.isInteger() = finalClass().primitiveName().equals("Integer");
220    eq InstClassDecl.isBoolean() = finalClass().primitiveName().equals("Boolean");
221    eq InstClassDecl.isString()  = finalClass().primitiveName().equals("String");
222    eq InstClassDecl.isEnum()    = extendsEnum();
223    eq InstClassDecl.isPartialFunction() = isPartial() && isFunction();
224   
225    eq InstBuiltIn.isReal() = 
226        myInstClass().finalClass().primitiveName().equals("RealType");
227    eq InstBuiltIn.isInteger() = 
228        myInstClass().finalClass().primitiveName().equals("IntegerType");
229    eq InstBuiltIn.isBoolean() = 
230        myInstClass().finalClass().primitiveName().equals("BooleanType");
231    eq InstBuiltIn.isString() = 
232        myInstClass().finalClass().primitiveName().equals("StringType");
233
234    syn CommonType InstAssignable.commonType() = type();
235   
236    eq InstRecord.commonType() {
237        Map<Index, InstComponentDecl> decls = new HashMap<>();
238        for (Index index : indices()) {
239            InstComponentDecl decl = this;
240            for (int i = 0; i < index.ndims(); i++) {
241                if (decl.hasInstComponentDecl()) {
242                    decl = decl.getInstComponentDecl(index.get(i) - 1);
243                }
244            }
245            decls.put(index.fix(), decl);
246        }
247        return new ArrayType(indices(), decls, type().scalarType());
248    }
249}
250
251
252aspect InstBindingType {
253
254    syn CommonType InstAssignable.expectedBindingType() = expectedBindingType(true);
255    syn CommonType InstAssignable.expectedBindingTypeNoEach() = expectedBindingType(false);
256
257    syn CommonType InstAssignable.expectedBindingType(boolean useEach) {
258        InstValueModification ivm = myInstValueMod();
259        return type().sizedType(ivm.expectedSize(useEach));
260    }
261   
262    eq InstRecord.expectedBindingType(boolean useEach) {
263        InstValueModification ivm = myInstValueMod();
264        Size arraySize = ivm.expectedSize(useEach).contractRight(indexInModification(useEach).ndims());
265        return commonType().expand(arraySize);
266    }
267
268    syn CommonType InstAssignable.actualBindingType() {
269        FExp bexp = myBindingInstExp();
270        if (bexp.type().isRecord() && bexp.size().equals(bexp.getArray().size())) {
271            Array array = bexp.getArray();
272            Map<Index, FExp> exps = new HashMap<>();
273            for (Index i : bexp.indices()) {
274                exps.put(i.fix(), array.get(i));
275            }
276            return new ArrayType(bexp.indices(), exps, bexp.type().scalarType());
277        }
278        return bexp.type();
279    }
280
281    /**
282     * If this assignable is in a modification on an array, return the index for this instance.
283     */
284    syn Index InstAssignable.indexInModification() = indexInModification(true);
285    syn Index InstAssignable.indexInModificationNoEach() = indexInModification(false);
286
287    syn Index InstAssignable.indexInModification(boolean useEach) {
288        int ndims = myInstValueMod().expectedSize(useEach).ndims() - size().ndims();
289        Index arrayIndex = parentTotalIndex();
290        return arrayIndex.subIndex(arrayIndex.ndims() - ndims);
291    }
292
293    /**
294     * The size that a value FExp of this modification should have.
295     */
296    syn Size InstModification.expectedSize() = expectedSize(true);
297
298    /**
299     * The size that a value FExp of this modification should have, if all 'each' are ignored.
300     */
301    syn Size InstModification.expectedSizeNoEach() = expectedSize(false);
302
303    /**
304     * The size that a value FExp of this modification should have.
305     *
306     * @param useEach  if <code>false</code>, ignore any each
307     */
308    syn Size InstModification.expectedSize(boolean useEach) = expectedSizeFromParent(useEach);
309    eq InstNamedModification.expectedSize(boolean useEach)  = 
310        getName().myInstComponentDecl().size().expand(useEach && getEach() ? Size.SCALAR : super.expectedSize(useEach));
311    eq InstElementRedeclare.expectedSize(boolean useEach)   = getName().myInstComponentDecl().size();
312
313    /**
314     * The size that a value expression of the parent this modification should have.
315     */
316    syn Size InstModification.expectedSizeFromParent() = expectedSizeFromParent(true);
317
318    /**
319     * The size that a value expression of the parent this modification should have.
320     *
321     * @param useEach  if <code>false</code>, ignore any each
322     */
323    inh Size InstModification.expectedSizeFromParent(boolean useEach);
324    eq InstModification.getChild().expectedSizeFromParent(boolean useEach)      = expectedSize(useEach);
325    eq InstComponentDecl.getChild().expectedSizeFromParent(boolean useEach)     = size();
326    eq InstClassDecl.getChild().expectedSizeFromParent(boolean useEach)         = size();
327    eq InstConstrainingClass.getChild().expectedSizeFromParent(boolean useEach) = getClassName().myInstClassDecl().size();
328    eq Root.getChild().expectedSizeFromParent(boolean useEach) {
329        throw new UnsupportedOperationException();
330    }
331
332    /**
333     * Find the modification, if any, on which 'each' could be added to make all contained array sizes fit.
334     *
335     * @param s  the size to be matched to this modification
336     * @return  the matching modification, or <code>null</code> if none is found.
337     */
338    syn InstModification InstModification.findModificationLackingEach(Size s) {
339        Size es = expectedSize();
340        if (s.ndims() < es.ndims() && es.contractLeft(s.ndims()).equivalent(s, true)) 
341            return findOrRetrieveModificationLackingEach(s);
342        else
343            return null;
344    }
345
346    /**
347     * Check if this modification could be lacking each, or look upwards in tree otherwise.
348     *
349     * @param s  the size to match against
350     */
351    syn InstModification InstModification.findOrRetrieveModificationLackingEach(Size s) = retrieveModificationLackingEach(s);
352    eq InstNamedModification.findOrRetrieveModificationLackingEach(Size s) {
353        int mnd = getName().ndims();
354        int snd = s.ndims();
355        if (mnd > snd)
356            return null;
357        Size ns = s.contract(0, mnd);
358        if (mnd < snd)
359            return retrieveModificationLackingEach(ns);
360        if (allModificationsMatchesSize(ns)) {
361            InstModification outside = retrieveModificationLackingEach(ns);
362            return (outside == null) ? this : outside;
363        }
364        return null;
365    }
366
367    /**
368     * Look upwards in tree for a modification that could be lacking each.
369     *
370     * @param s  the size to match against
371     */
372    inh InstModification InstModification.retrieveModificationLackingEach(Size s);
373    eq InstNode.getChild().retrieveModificationLackingEach(Size s)              = null;
374    eq InstRecordConstructor.getChild().retrieveModificationLackingEach(Size s) = null;
375    eq InstElementRedeclare.getChild().retrieveModificationLackingEach(Size s)  = null;
376    eq InstNamedModification.getChild().retrieveModificationLackingEach(Size s) = findOrRetrieveModificationLackingEach(s);
377
378    /**
379     * Check if the sizes all expressions in this modification matches <code>s</code> as size of this modification.
380     */
381    syn boolean InstModification.allModificationsMatchesSize(Size s)     = true;
382    eq InstArrayModification.allModificationsMatchesSize(Size s)         = true;
383    eq InstElementRedeclare.allModificationsMatchesSize(Size s)          = true;
384    eq InstValueModification.allModificationsMatchesSize(Size s)         = getFExp().size().equivalent(s, true);
385    eq InstCompleteModification.allModificationsMatchesSize(Size s)      = 
386        getInstClassModification().allModificationsMatchesSize(s) && 
387        (!hasInstValueModification() || getInstValueModification().allModificationsMatchesSize(s));
388    eq InstClassModification.allModificationsMatchesSize(Size s) {
389        for (InstArgument ia : getInstArguments())
390            if (!ia.allModificationsMatchesSize(s))
391                return false;
392        return true;
393    }
394    eq InstElementModification.allModificationsMatchesSize(Size s) {
395        if (getEach() || !hasInstModification())
396            return true;
397        else
398            return getInstModification().allModificationsMatchesSize(s.expandRight(getName().size()));
399    }
400
401
402    /**
403     * Check if node is the same as this or the class of this component (if this is a component).
404     */
405    syn boolean InstNode.isMeOrMyClass(InstNode node) = node == this;
406    eq InstClassDecl.isMeOrMyClass(InstNode node)     = node.inheritingNode() == this;
407    eq InstComponentDecl.isMeOrMyClass(InstNode node) {
408        InstNode inherit = node.inheritingNode();
409        return inherit == this || inherit == myInstClass();
410    }
411
412    /**
413     * If this is an extends, get the surrounding class or component, otherwise return this.
414     */
415    syn InstNode InstNode.inheritingNode() = this;
416    eq InstExtends.inheritingNode()        = findInheritingNode();
417
418    /**
419     * Find the surrounding class or component.
420     */
421    inh InstNode InstExtends.findInheritingNode();
422    eq InstClassDecl.getInstExtends().findInheritingNode()     = this;
423    eq InstComponentDecl.getInstExtends().findInheritingNode() = this;
424    eq Root.getChild().findInheritingNode()                    = null;
425
426    /**
427     * Find the surrounding class, if any.
428     */
429    inh InstClassDecl InstNode.surroundingInstClass();
430    inh InstClassDecl InstExternal.surroundingInstClass();
431    inh InstClassDecl FGetInstanceName.surroundingInstClass();
432    eq InstClassDecl.getChild().surroundingInstClass() = this;
433    eq InstLibNode.getChild().surroundingInstClass()   = surroundingInstClass();
434    eq Root.getChild().surroundingInstClass()          = null;
435
436    /**
437     * Is this a member of an array component?
438     */
439    inh boolean InstAssignable.inArrayComponent();
440    eq InstClassDecl.getChild().inArrayComponent()          = false;
441    eq InstRoot.getChild().inArrayComponent()               = false;
442    eq FlatRoot.getChild().inArrayComponent()               = false;
443    eq InstArrayComponentDecl.getChild().inArrayComponent() = true;
444    syn boolean InstNode.inArrayComponent()                 = false;
445
446}
447
448
449aspect NodeTypes {
450
451    /**
452     * Is this element a short class decl?
453     */
454    syn boolean SrcElement.isShortClassDecl() = false;
455    eq SrcShortClassDecl.isShortClassDecl()   = true;
456
457    syn SrcShortClassDecl SrcElement.asShortClassDecl() {
458        throw new UnsupportedOperationException("asShortClassDecl() is not supported for class type " + getClass().getSimpleName());
459    }
460    eq SrcShortClassDecl.asShortClassDecl() = this;
461
462    /**
463     * Is this element a full class decl?
464     */
465    syn boolean SrcElement.isFullClassDecl() = false;
466    eq SrcFullClassDecl.isFullClassDecl()    = true;
467
468    syn SrcFullClassDecl SrcElement.asFullClassDecl() {
469        throw new UnsupportedOperationException("asFullClassDecl() is not supported for class type " + getClass().getSimpleName());
470    }
471    eq SrcFullClassDecl.asFullClassDecl() = this;
472}
473
474
475aspect ClassRestriction {
476
477    /**
478     * Is this class partial?
479     */
480    syn boolean SrcClassDecl.isPartial() = false;
481    eq SrcBaseClassDecl.isPartial()      = getPartial();
482    eq SrcLibNode.isPartial()            = myClass().isPartial();
483
484    /**
485     * Is this class encapsulated?
486     */
487    syn boolean SrcClassDecl.isEncapsulated() = false;
488    eq SrcBaseClassDecl.isEncapsulated()      = getEncapsulated();
489    eq SrcLibNode.isEncapsulated()            = myClass().isEncapsulated();
490
491    /**
492     * Is this class a model?
493     */
494    syn boolean SrcClassDecl.isModel() = false;
495    eq SrcBaseClassDecl.isModel()      = getSrcRestriction().isModel();
496    eq SrcLibNode.isModel()            = myClass().isModel();
497
498    /**
499     * Is this restriction "model"?
500     */
501    syn boolean SrcRestriction.isModel() = false;
502    eq SrcModel.isModel()                = true;
503
504    /**
505     * Is this class a block?
506     */
507    syn boolean SrcClassDecl.isBlock() = false;
508    eq SrcBaseClassDecl.isBlock()      = getSrcRestriction().isBlock();
509    eq SrcLibNode.isBlock()            = myClass().isBlock();
510
511    /**
512     * Is this restriction "block"?
513     */
514    syn boolean SrcRestriction.isBlock() = false;
515    eq SrcBlock.isBlock()                = true;
516
517    /**
518     * Is this class a class?
519     */
520    syn boolean SrcClassDecl.isClass() = false;
521    eq SrcBaseClassDecl.isClass()      = getSrcRestriction().isClass();
522    eq SrcLibNode.isClass()            = myClass().isClass();
523
524    /**
525     * Is this restriction "class"?
526     */
527    syn boolean SrcRestriction.isClass() = false;
528    eq SrcClass.isClass()               = true;
529
530    /**
531     * Is this class a package?
532     */
533    syn boolean SrcClassDecl.isPackage() = false;
534    eq SrcBaseClassDecl.isPackage()      = getSrcRestriction().isPackage();
535    eq SrcUnknownClassDecl.isPackage()   = false;
536    eq SrcLibNode.isPackage()            = myClass().isPackage();
537
538    /**
539     * Is this restriction "package"?
540     */
541    syn boolean SrcRestriction.isPackage() = false;
542    eq SrcPackage.isPackage()             = true;
543
544}
545
546
547aspect InstClassRestriction {
548
549    /**
550     * Is this class partial?
551     */
552    syn boolean InstClassDecl.isPartial() = getSrcClassDecl().isPartial();
553
554    /**
555     * Is this class encapsulated?
556     */
557    syn boolean InstClassDecl.isEncapsulated() = getSrcClassDecl().isEncapsulated();
558
559    /**
560     * Is this class a connector?
561     */
562    syn boolean InstClassDecl.isConnector() = false;
563    eq InstBaseClassDecl.isConnector()      = getInstRestriction().isConnector();
564    eq UnknownInstClassDecl.isConnector()   = false;
565
566    /**
567     * Is this restriction "connector"?
568     */
569    syn boolean InstRestriction.isConnector() = false;
570    eq InstConnector.isConnector() = true;
571
572    /**
573     * Is this component a connector?
574     */
575    syn boolean InstComponentDecl.isConnector() = myInstClass().isConnector();
576
577    /**
578     * Is this class an expandable connector?
579     */
580    syn boolean InstClassDecl.isExpandableConnector() = false;
581    eq InstBaseClassDecl.isExpandableConnector()      = getInstRestriction().isExpandableConnector();
582    eq UnknownInstClassDecl.isExpandableConnector()   = false;
583
584    /**
585     * Is this restriction "expandable connector"?
586     */
587    syn boolean InstRestriction.isExpandableConnector() = false;
588    eq InstExpandableConnector.isExpandableConnector()  = true;
589
590    /**
591     * Is this component an expandable connector?
592     */
593    syn boolean InstComponentDecl.isExpandableConnector() = myInstClass().isExpandableConnector();
594
595    /**
596     * Is this class an operator record?
597     */
598    syn boolean InstClassDecl.isOperatorRecord() = false;
599    eq InstBaseClassDecl.isOperatorRecord()      = getInstRestriction().isOperatorRecord();
600    eq UnknownInstClassDecl.isOperatorRecord()   = false;
601
602    /**
603     * Is this restriction "operator record"?
604     */
605    syn boolean InstRestriction.isOperatorRecord() = false;
606    eq InstOperatorRecord.isOperatorRecord()       = true;
607    eq InstConnector.isOperatorRecord()            = 
608        (inheritedRestriction() != null) ? inheritedRestriction().isOperatorRecord() : super.isOperatorRecord();
609
610    /**
611     * Is this component an operator record?
612     */
613    syn boolean InstComponentDecl.isOperatorRecord() = false;
614    eq InstRecord.isOperatorRecord()                 = myInstClass().isOperatorRecord();
615
616    /**
617     * Is this class an operator?
618     */
619    syn boolean InstClassDecl.isOperator() = false;
620    eq InstBaseClassDecl.isOperator()      = getInstRestriction().isOperator();
621    eq UnknownInstClassDecl.isOperator()   = false;
622
623    /**
624     * Is this restriction "operator" or "operator function"?
625     */
626    syn boolean InstRestriction.isOperator() = false;
627    eq InstOperator.isOperator()             = true;
628    eq InstOperatorFunction.isOperator()     = true;
629
630    /**
631     * Is this class a function?
632     */
633    syn boolean InstNode.isFunction()      = false;
634    eq InstBaseClassDecl.isFunction()      = getInstRestriction().isFunction();
635    eq UnknownInstClassDecl.isFunction()   = false;
636
637    /**
638     * Is this restriction "function"?
639     */
640    syn boolean InstRestriction.isFunction() = false;
641    eq InstFunction.isFunction() = true;
642
643    /**
644     * Is this class a record?
645     */
646    syn boolean InstClassDecl.isRecord() = false;
647    eq InstBaseClassDecl.isRecord()      = getInstRestriction().isRecord();
648    eq UnknownInstClassDecl.isRecord()   = false;
649
650    /**
651     * Is this restriction "record"?
652     */
653    syn boolean InstRestriction.isRecord() = false;
654    eq InstMRecord.isRecord()              = true;
655    eq InstConnector.isRecord()            = 
656        (inheritedRestriction() != null) ? inheritedRestriction().isRecord() : super.isRecord();
657
658    /**
659     * Is this class a function or record?
660     */
661    syn boolean InstClassDecl.isCallable() = false;
662    eq InstBaseClassDecl.isCallable()      = getInstRestriction().isCallable();
663    eq UnknownInstClassDecl.isCallable()   = false;
664   
665    syn boolean InstPartialFunction.isCallable() = true;
666   
667    /**
668     * Is this restriction "function" or "record"?
669     */
670    syn boolean InstRestriction.isCallable() = false;
671    eq InstFunction.isCallable()             = true;
672    eq InstMRecord.isCallable()              = true;
673    eq InstConnector.isCallable()            = 
674        (inheritedRestriction() != null) ? inheritedRestriction().isCallable() : super.isCallable();
675
676    /**
677     * Is this class a package?
678     */
679    syn boolean InstClassDecl.isPackage() = false;
680    eq InstBaseClassDecl.isPackage()      = getInstRestriction().isPackage();
681    eq UnknownInstClassDecl.isPackage()   = false;
682
683    /**
684     * Is this restriction "package"?
685     */
686    syn boolean InstRestriction.isPackage() = false;
687    eq InstMPackage.isPackage()             = true;
688
689    /**
690     * Is this class a model?
691     */
692    syn boolean InstClassDecl.isModel() = false;
693    eq InstBaseClassDecl.isModel()      = getInstRestriction().isModel();
694    eq UnknownInstClassDecl.isModel()   = false;
695
696    /**
697     * Is this restriction "model"?
698     */
699    syn boolean InstRestriction.isModel() = false;
700    eq InstModel.isModel()                = true;
701
702    /**
703     * Is this class a block?
704     */
705    syn boolean InstClassDecl.isBlock() = false;
706    eq InstBaseClassDecl.isBlock()      = getInstRestriction().isBlock();
707    eq UnknownInstClassDecl.isBlock()   = false;
708
709    /**
710     * Is this restriction "block"?
711     */
712    syn boolean InstRestriction.isBlock() = false;
713    eq InstBlock.isBlock()                = true;
714
715    /**
716     * Is this class a class?
717     */
718    syn boolean InstClassDecl.isClass() = false;
719    eq InstBaseClassDecl.isClass()      = getInstRestriction().isClass();
720    eq UnknownInstClassDecl.isClass()   = false;
721
722    /**
723     * Is this restriction "class"?
724     */
725    syn boolean InstRestriction.isClass() = false;
726    eq InstMClass.isClass()               = true;
727
728    /**
729     * Is this class an external object?
730     */
731    syn boolean InstClassDecl.isExternalObject() {
732        for (InstExtends ie : getInstExtendss()) {
733            String name = ie.getClassName().name();
734            if (name.equals("ExternalObject"))
735                return true;
736        }
737        return false;
738    }
739    eq InstSimpleShortClassDecl.isExternalObject() = actualInstClass().isExternalObject();
740    eq InstLibNode.isExternalObject()              = actualInstClass().isExternalObject();
741
742    /**
743     * Check if this class has a restriction.
744     */
745    syn boolean InstClassDecl.hasInstRestriction() = false;
746    eq InstBaseClassDecl.hasInstRestriction()      = true;
747    eq InstBuiltInClassDecl.hasInstRestriction()   = true;
748
749    /**
750     * Get the restriction of this class.
751     */
752    public InstRestriction InstClassDecl.getInstRestriction() {
753        throw new UnsupportedOperationException();
754    }
755
756    public InstRestriction InstBuiltInClassDecl.getInstRestriction() {
757        return root().getInstBuiltInClassRestriction();
758    }
759   
760    syn nta InstRestriction Root.getInstBuiltInClassRestriction() = new InstMType();
761
762}
763
764
765aspect InstModificationType {
766   
767    /**
768     * Is this modification final?
769     */
770    syn boolean InstModification.isFinal() = inheritsFinal();
771    eq InstArgument.isFinal()              = getFinal() || inheritsFinal();
772   
773    /**
774     * Is this modification within another modification or component that is declared final?
775     */
776    inh boolean InstModification.inheritsFinal();
777    inh boolean InstComponentDecl.inheritsFinal();
778    inh boolean InstExtends.inheritsFinal();
779    eq InstModification.getChild().inheritsFinal()  = isFinal();
780    eq InstComponentDecl.getChild().inheritsFinal() = getSrcComponentDecl().hasFinal() || inheritsFinal();
781    eq InstExtends.getChild().inheritsFinal()       = inheritsFinal();
782    eq BaseNode.getChild().inheritsFinal()          = false;
783
784}
Note: See TracBrowser for help on using the repository browser.