Skip to content
This repository
Browse code

Merge branch 'master' into defaulttypeargs

Merged ExpressionVisitor

Conflicts:
	src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java
  • Loading branch information...
commit 5dc0ed004ed5c84f132b3cead41ca19fb4e03cb2 2 parents 07643a9 + 1e5d9d1
Stéphane Épardaud authored January 11, 2013
16  src/com/redhat/ceylon/compiler/typechecker/analyzer/DeclarationVisitor.java
@@ -461,7 +461,7 @@ public void visit(Tree.AttributeDeclaration that) {
461 461
         		instanceof Tree.LazySpecifierExpression);
462 462
         visitDeclaration(that, v);
463 463
         super.visit(that);
464  
-        if (v.isInterfaceMember() && !v.isFormal()) {
  464
+        if (v.isInterfaceMember() && !v.isFormal() && !v.isNative()) {
465 465
             if (that.getSpecifierOrInitializerExpression()==null) {
466 466
                 that.addError("interface attribute must be annotated formal", 1400);
467 467
             }
@@ -888,6 +888,9 @@ else if (that instanceof Tree.Parameter) {
888 888
                 model.setFormal(true);
889 889
             }
890 890
         }
  891
+        if (hasAnnotation(al, "native")) {
  892
+        	model.setNative(true);
  893
+        }
891 894
         if (model.isFormal() && model.isDefault()) {
892 895
             that.addError("declaration may not be annotated both formal and default");
893 896
         }
@@ -981,7 +984,16 @@ private static void checkFormalMember(Tree.Declaration that, Declaration d) {
981 984
             	!(that instanceof Tree.Parameter)) {
982 985
             	that.addError("formal member may not have a body", 1100);
983 986
             }
984  
-        }        
  987
+        }
  988
+        
  989
+        if (d.isNative()) {
  990
+        	if (d.getContainer() instanceof Declaration) {
  991
+        		Declaration ci = (Declaration) d.getContainer();
  992
+        		if (!ci.isNative()) {
  993
+        			that.addError("native member belongs to a non-native declaration");
  994
+        		}
  995
+        	}
  996
+        }
985 997
         
986 998
         /*if ( !d.isFormal() && 
987 999
                 d.getContainer() instanceof Interface && 
35  src/com/redhat/ceylon/compiler/typechecker/analyzer/ExpressionVisitor.java
@@ -86,6 +86,7 @@
86 86
     private Tree.Expression switchExpression;
87 87
     private Declaration returnDeclaration;
88 88
     private boolean defaultArgument;
  89
+    private boolean isCondition;
89 90
 
90 91
     private Unit unit;
91 92
     
@@ -261,7 +262,9 @@ private void initOriginalDeclaration(Tree.Variable that) {
261 262
         //want to check that the specifier expression is
262 263
         //assignable to the declared variable type
263 264
         //(nor is it possible to infer the variable type)
  265
+    	isCondition=true;
264 266
         that.getType().visit(this);
  267
+        isCondition=false;
265 268
         Tree.Variable v = that.getVariable();
266 269
         ProducedType type = that.getType().getTypeModel();
267 270
         if (v!=null) {
@@ -4133,11 +4136,11 @@ private static boolean isGeneric(Declaration member) {
4133 4136
             !((Generic) member).getTypeParameters().isEmpty();
4134 4137
     }
4135 4138
     
4136  
-    private boolean acceptsTypeArguments(ProducedType receiver, Declaration member, 
  4139
+    private boolean acceptsTypeArguments(ProducedType receiver, Declaration dec, 
4137 4140
             List<ProducedType> typeArguments, Tree.TypeArguments tal, Node parent) {
4138  
-        if (member==null) return false;
4139  
-        if (isGeneric(member)) {
4140  
-            List<TypeParameter> params = ((Generic) member).getTypeParameters();
  4141
+        if (dec==null) return false;
  4142
+        if (isGeneric(dec)) {
  4143
+            List<TypeParameter> params = ((Generic) dec).getTypeParameters();
4141 4144
             int min = 0;
4142 4145
             for (TypeParameter tp: params) { 
4143 4146
             	if (!tp.isDefaulted()) min++;
@@ -4151,19 +4154,19 @@ private boolean acceptsTypeArguments(ProducedType receiver, Declaration member,
4151 4154
                     //Map<TypeParameter, ProducedType> self = Collections.singletonMap(param, arg);
4152 4155
                     for (ProducedType st: param.getSatisfiedTypes()) {
4153 4156
                         //sts = sts.substitute(self);
4154  
-                        ProducedType sts = st.getProducedType(receiver, member, typeArguments);
  4157
+                        ProducedType sts = st.getProducedType(receiver, dec, typeArguments);
4155 4158
                         if (argType!=null) {
4156  
-                            if (!argType.isSubtypeOf(sts)) {
  4159
+                            if (!isCondition && !argType.isSubtypeOf(sts)) {
4157 4160
                                 if (tal instanceof Tree.InferredTypeArguments) {
4158 4161
                                     parent.addError("inferred type argument " + argType.getProducedTypeName(unit)
4159 4162
                                             + " to type parameter " + param.getName()
4160  
-                                            + " of declaration " + member.getName(unit)
  4163
+                                            + " of declaration " + dec.getName(unit)
4161 4164
                                             + " not assignable to " + sts.getProducedTypeName(unit));
4162 4165
                                 }
4163 4166
                                 else {
4164 4167
                                     ((Tree.TypeArgumentList) tal).getTypes()
4165 4168
                                             .get(i).addError("type parameter " + param.getName() 
4166  
-                                            + " of declaration " + member.getName(unit)
  4169
+                                            + " of declaration " + dec.getName(unit)
4167 4170
                                             + " has argument " + argType.getProducedTypeName(unit) 
4168 4171
                                             + " not assignable to " + sts.getProducedTypeName(unit), 2102);
4169 4172
                                 }
@@ -4171,19 +4174,19 @@ private boolean acceptsTypeArguments(ProducedType receiver, Declaration member,
4171 4174
                             }
4172 4175
                         }
4173 4176
                     }
4174  
-                    boolean asec = argumentSatisfiesEnumeratedConstraint(receiver, member, 
4175  
-                            typeArguments, argType, param);
4176  
-                    if (!asec) {
  4177
+                    if (!isCondition && 
  4178
+                    		!argumentSatisfiesEnumeratedConstraint(receiver, dec, 
  4179
+                                    typeArguments, argType, param)) {
4177 4180
                         if (tal instanceof Tree.InferredTypeArguments) {
4178 4181
                             parent.addError("inferred type argument " + argType.getProducedTypeName(unit)
4179 4182
                                     + " to type parameter " + param.getName()
4180  
-                                    + " of declaration " + member.getName(unit)
  4183
+                                    + " of declaration " + dec.getName(unit)
4181 4184
                                     + " not one of the enumerated cases");
4182 4185
                         }
4183 4186
                         else {
4184 4187
                             ((Tree.TypeArgumentList) tal).getTypes()
4185 4188
                             .get(i).addError("type parameter " + param.getName() 
4186  
-                                    + " of declaration " + member.getName(unit)
  4189
+                                    + " of declaration " + dec.getName(unit)
4187 4190
                                     + " has argument " + argType.getProducedTypeName(unit) 
4188 4191
                                     + " not one of the enumerated cases");
4189 4192
                         }
@@ -4194,7 +4197,7 @@ private boolean acceptsTypeArguments(ProducedType receiver, Declaration member,
4194 4197
             }
4195 4198
             else {
4196 4199
                 if (tal==null || tal instanceof Tree.InferredTypeArguments) {
4197  
-                    parent.addError("requires type arguments: " + member.getName(unit));
  4200
+                    parent.addError("requires type arguments: " + dec.getName(unit));
4198 4201
                 }
4199 4202
                 else {
4200 4203
                 	String help="";
@@ -4205,7 +4208,7 @@ else if (args>max) {
4205 4208
                 		help = " (allows at most " + max + " type arguments)";
4206 4209
                 	}
4207 4210
                     tal.addError("wrong number of type arguments to: " + 
4208  
-                    		member.getName(unit) + help);
  4211
+                    		dec.getName(unit) + help);
4209 4212
                 }
4210 4213
                 return false;
4211 4214
             }
@@ -4214,7 +4217,7 @@ else if (args>max) {
4214 4217
             boolean empty = typeArguments.isEmpty();
4215 4218
             if (!empty) {
4216 4219
                 tal.addError("does not accept type arguments: " + 
4217  
-                        member.getName(unit));
  4220
+                        dec.getName(unit));
4218 4221
             }
4219 4222
             return empty;
4220 4223
         }
3  src/com/redhat/ceylon/compiler/typechecker/analyzer/RefinementVisitor.java
@@ -224,7 +224,8 @@ private boolean includedImplicitely(Module importedModule, Module targetModule,
224 224
 
225 225
 	private void validateRefinement(Tree.StatementOrArgument that, TypeDeclaration td) {
226 226
 		List<ProducedType> supertypes = td.getType().getSupertypes();
227  
-		if (td instanceof TypeAlias) {
  227
+		if (td instanceof TypeAlias && 
  228
+				td.getExtendedType()!=null) {
228 229
 			supertypes.add(td.getExtendedType());
229 230
 		}
230 231
 		for (int i=0; i<supertypes.size(); i++) {
21  src/com/redhat/ceylon/compiler/typechecker/analyzer/SpecificationVisitor.java
@@ -174,7 +174,13 @@ else if (!specified.definitely) {
174 174
                     //you are allowed to refer to formal
175 175
                     //declarations in a class declaration
176 176
                     //section or interface
177  
-                    if (!declaration.isFormal()) {
  177
+                    if (declaration.isFormal()) {
  178
+						if (!isForwardReferenceable()) {
  179
+						    that.addError("formal member may not be used in initializer: " + 
  180
+						            member.getName());                    
  181
+						}
  182
+					}
  183
+                    else if (!declaration.isNative()) {
178 184
                         if (isVariable()) {
179 185
                             that.addError("not definitely initialized: " + 
180 186
                                     member.getName());                    
@@ -184,10 +190,6 @@ else if (!specified.definitely) {
184 190
                                     member.getName());
185 191
                         }
186 192
                     }
187  
-                    else if (!isForwardReferenceable()) {
188  
-                        that.addError("formal member may not be used in initializer: " + 
189  
-                                member.getName());                    
190  
-                    }
191 193
                 }
192 194
                 if (!mte.getAssigned() && member.isDefault() && 
193 195
                         !isForwardReferenceable()) {
@@ -375,11 +377,12 @@ public void visit(Tree.MethodDeclaration that) {
375 377
             if (that.getSpecifierExpression()!=null) {
376 378
                 specify();
377 379
             }
378  
-            else if (declaration.isToplevel()) {
  380
+            else if (declaration.isToplevel() && !declaration.isNative()) {
379 381
                 that.addError("toplevel function must be specified: " +
380 382
                         declaration.getName());
381 383
             }
382  
-            else if (declaration.isInterfaceMember() && !declaration.isFormal()) {
  384
+            else if (declaration.isInterfaceMember() && 
  385
+            		!declaration.isFormal() && !declaration.isNative()) {
383 386
                 that.addError("interface method must be formal or specified: " +
384 387
                         declaration.getName(), 1400);
385 388
             }
@@ -589,8 +592,10 @@ public void visit(Tree.Return that) {
589 592
     }
590 593
 
591 594
     private boolean isSharedDeclarationUninitialized() {
592  
-        return (declaration.isShared() || declaration.isCaptured()) && 
  595
+        return (declaration.isShared() || 
  596
+        		    declaration.isCaptured()) && 
593 597
                 !declaration.isFormal() && 
  598
+                !declaration.isNative() &&
594 599
                 !specified.definitely;
595 600
     }
596 601
     
20  src/com/redhat/ceylon/compiler/typechecker/analyzer/TypeVisitor.java
@@ -718,7 +718,11 @@ else if (et instanceof Tree.QualifiedType) {
718 718
             else {
719 719
                 ProducedType type = et.getTypeModel();
720 720
                 if (type!=null) {
721  
-                    if (type.getDeclaration() instanceof Class) {
  721
+                	if (type.containsTypeAliases()) {
  722
+                		et.addError("aliased type involves type aliases: " +
  723
+                				type.getProducedTypeName());
  724
+                	}
  725
+                	else if (type.getDeclaration() instanceof Class) {
722 726
                     	that.getDeclarationModel().setExtendedType(type);
723 727
                     } 
724 728
                     else {
@@ -748,7 +752,11 @@ else if (!(et instanceof Tree.StaticType)) {
748 752
             else {
749 753
                 ProducedType type = et.getTypeModel();
750 754
                 if (type!=null) {
751  
-                    if (type.getDeclaration() instanceof Interface) {
  755
+                	if (type.containsTypeAliases()) {
  756
+                		et.addError("aliased type involves type aliases: " +
  757
+                				type.getProducedTypeName());
  758
+                	}
  759
+                	else if (type.getDeclaration() instanceof Interface) {
752 760
                     	that.getDeclarationModel().setExtendedType(type);
753 761
                     } 
754 762
                     else {
@@ -774,7 +782,13 @@ public void visit(Tree.TypeAliasDeclaration that) {
774 782
             else {
775 783
                 ProducedType type = et.getTypeModel();
776 784
                 if (type!=null) {
777  
-                    that.getDeclarationModel().setExtendedType(type);
  785
+                	if (type.containsTypeAliases()) {
  786
+                		et.addError("aliased type involves type aliases: " +
  787
+                				type.getProducedTypeName());
  788
+                	}
  789
+                	else {
  790
+                		that.getDeclarationModel().setExtendedType(type);
  791
+                	}
778 792
                 }
779 793
             }
780 794
         }
11  src/com/redhat/ceylon/compiler/typechecker/model/Declaration.java
@@ -28,6 +28,7 @@
28 28
     private boolean staticallyImportable;
29 29
     private boolean protectedVisibility;
30 30
     private String qualifiedNameAsStringCache;
  31
+	private boolean nat;
31 32
 
32 33
     public Scope getVisibleScope() {
33 34
         return visibleScope;
@@ -101,11 +102,19 @@ public void setActual(boolean actual) {
101 102
     public boolean isFormal() {
102 103
         return formal;
103 104
     }
104  
-
  105
+    
105 106
     public void setFormal(boolean formal) {
106 107
         this.formal = formal;
107 108
     }
108 109
 
  110
+    public boolean isNative() {
  111
+    	return nat;
  112
+    }
  113
+    
  114
+    public void setNative(boolean nat) {
  115
+    	this.nat=nat;
  116
+    }
  117
+
109 118
     public boolean isDefault() {
110 119
         return def;
111 120
     }
63  src/com/redhat/ceylon/compiler/typechecker/model/ProducedType.java
@@ -1625,6 +1625,9 @@ else if (sdt instanceof TypeParameter && !typeParams) {
1625 1625
     
1626 1626
     public void setUnderlyingType(String underlyingType) {
1627 1627
         this.underlyingType = underlyingType;
  1628
+        // if we have a resolvedAliases cache, update it too
  1629
+        if(resolvedAliases != null && resolvedAliases != this)
  1630
+            resolvedAliases.setUnderlyingType(underlyingType);
1628 1631
     }
1629 1632
     
1630 1633
     public String getUnderlyingType() {
@@ -1684,6 +1687,9 @@ public boolean isRaw() {
1684 1687
 
1685 1688
     public void setRaw(boolean isRaw) {
1686 1689
         this.isRaw = isRaw;
  1690
+        // if we have a resolvedAliases cache, update it too
  1691
+        if(resolvedAliases != null && resolvedAliases != this)
  1692
+            resolvedAliases.setRaw(isRaw);
1687 1693
     }
1688 1694
     
1689 1695
     public ProducedType resolveAliases() {
@@ -1693,6 +1699,11 @@ public ProducedType resolveAliases() {
1693 1699
             resolvedAliases = curriedResolveAliases();
1694 1700
             // mark it as resolved so it doesn't get resolved again
1695 1701
             resolvedAliases.resolvedAliases = resolvedAliases;
  1702
+            if(resolvedAliases != this){
  1703
+                // inherit whatever underlying type we had
  1704
+                resolvedAliases.underlyingType = underlyingType;
  1705
+                resolvedAliases.isRaw = isRaw;
  1706
+            }
1696 1707
         }
1697 1708
         return resolvedAliases;
1698 1709
     	//return curriedResolveAliases();
@@ -1739,4 +1750,56 @@ private ProducedType curriedResolveAliases() {
1739 1750
     	}
1740 1751
     }
1741 1752
     
  1753
+    public boolean containsTypeParameters() {
  1754
+    	TypeDeclaration d = getDeclaration();
  1755
+		if (d instanceof TypeParameter) {
  1756
+			return true;
  1757
+		}
  1758
+		else if (d instanceof UnionType) {
  1759
+			for (ProducedType ct: getCaseTypes()) {
  1760
+				if (ct.containsTypeParameters()) return true;
  1761
+			}
  1762
+		}
  1763
+		else if (d instanceof IntersectionType) {
  1764
+			for (ProducedType st: getSatisfiedTypes()) {
  1765
+				if (st.containsTypeParameters()) return true;
  1766
+			}
  1767
+		}
  1768
+		else {
  1769
+			for (ProducedType at: getTypeArgumentList()) {
  1770
+				if (at.containsTypeParameters()) return true;
  1771
+			}
  1772
+			ProducedType qt = getQualifyingType();
  1773
+			if (qt!=null && qt.containsTypeParameters()) return true;
  1774
+		}
  1775
+		return false;
  1776
+    }
  1777
+    
  1778
+    public boolean containsTypeAliases() {
  1779
+    	TypeDeclaration d = getDeclaration();
  1780
+		if (d instanceof TypeAlias||
  1781
+			d instanceof ClassAlias||
  1782
+			d instanceof InterfaceAlias) {
  1783
+			return true;
  1784
+		}
  1785
+		else if (d instanceof UnionType) {
  1786
+			for (ProducedType ct: getCaseTypes()) {
  1787
+				if (ct.containsTypeAliases()) return true;
  1788
+			}
  1789
+		}
  1790
+		else if (d instanceof IntersectionType) {
  1791
+			for (ProducedType st: getSatisfiedTypes()) {
  1792
+				if (st.containsTypeAliases()) return true;
  1793
+			}
  1794
+		}
  1795
+		else {
  1796
+			for (ProducedType at: getTypeArgumentList()) {
  1797
+				if (at.containsTypeAliases()) return true;
  1798
+			}
  1799
+			ProducedType qt = getQualifyingType();
  1800
+			if (qt!=null && qt.containsTypeAliases()) return true;
  1801
+		}
  1802
+		return false;
  1803
+    }
  1804
+    
1742 1805
 }
4  test/main/aliases/Aliases.ceylon
@@ -86,7 +86,7 @@ class MemberClassAliasTricks_Foo(Integer a = 1, Integer b = 2){
86 86
     
87 87
     class MemberClassAliasToToplevel(Integer a, Integer b) 
88 88
             => MemberClassAliasTricks_Foo(a,b);
89  
-    class MemberClassAliasToToplevel2(Integer a, Integer b) 
  89
+    @error class MemberClassAliasToToplevel2(Integer a, Integer b) 
90 90
             => MemberClassAliasToToplevel(a,b);
91 91
 
92 92
     void test(){
@@ -94,3 +94,5 @@ class MemberClassAliasTricks_Foo(Integer a = 1, Integer b = 2){
94 94
         MemberClassAliasToToplevel2 m2 = MemberClassAliasToToplevel2(1,2);
95 95
     }
96 96
 }
  97
+
  98
+@error alias Rec<T> => Tuple<T,T,Rec<T>>;
2  test/main/aliases/inference.ceylon
@@ -16,7 +16,7 @@ void inference() {
16 16
     class E<U,V>(V v, U u) given U satisfies Object given V satisfies Object => Entry<V,U>(v,u);
17 17
     E<String,Integer> e = E(1, "hello");
18 18
     
19  
-    class ESL<T>(SSS<T> sss, SL<T> sl) given T satisfies Object => E<SL<T>, SSS<T>>(sss,sl);
  19
+    @error class ESL<T>(SSS<T> sss, SL<T> sl) given T satisfies Object => E<SL<T>, SSS<T>>(sss,sl);
20 20
     @type:"ESL<String>" value esl1 = ESL(SSS(Singleton(Singleton("hello"))), SL(["goodbye"]));
21 21
     ESL<Integer> esl2 = ESL(SSS(Singleton(Singleton(1))), SL([2,3]));
22 22
     Entry<Singleton<Singleton<Singleton<String>>>,Singleton<List<String>>> esl3 = 
17  test/main/aliases/unionintersection.ceylon
... ...
@@ -1,23 +1,28 @@
  1
+interface Container<out T> { shared Boolean empty=>false; }
1 2
 interface Cntnr => Container<Anything>; 
2 3
 
3 4
 alias Number => Integer|Float;
4  
-alias ListLike<T> given T satisfies Object => List<T>|Map<Integer,T>;
5  
-alias C => Cntnr&Category;
  5
+alias ListLike<T> given T satisfies Object => <List<T>|Map<Integer,T>>&Container<T>;
  6
+alias C => Container<Anything>&Category;
  7
+@error alias E => Cntnr&Category;
6 8
 
7 9
 Number n = 1;
8 10
 Number x = 2.0;
9  
-ListLike<Float> list = [ 1.0, 2.0 ];
  11
+[Float, Float]&Container<Float> pair = nothing;
  12
+ListLike<Float> list = pair;
10 13
 C c = list;
11 14
 
12 15
 shared alias Strings => List<String>;
13 16
 
14 17
 void local() {
15  
-    alias Numbers => List<Number>;
16  
-    Numbers ns = [ 1, 3.0 ];
  18
+    alias Numbers => List<Integer|Float>;
  19
+    Numbers numbers = [ 1, 3.0 ];
  20
+    @error alias Ns => List<Number>;
  21
+    @error Ns ns = [ 1, 3.0 ];
17 22
 }
18 23
 
19 24
 class Outer() {
20  
-    shared alias Cs => List<C>;
  25
+    shared alias Cs => List<Container<Anything>&Category>;
21 26
     shared Cs cs = [ c, c ];
22 27
 }
23 28
 
6  test/main/typing/Is.ceylon
@@ -17,9 +17,10 @@ class Is() {
17 17
         print(strings.first);
18 18
     }
19 19
     @error if (is Sequence strings) {}
20  
-    @error if (is SimpleContainer<String> strings) {}
  20
+    if (is SimpleContainer<String> strings) {}
21 21
     @error if (is Is.SimpleContainer strings) {}
22  
-    @error if (is Is.SimpleContainer<String> strings) {}
  22
+    if (is Is.SimpleContainer<String> strings) {}
  23
+    @error if (is Is.SimpleContainer<String,Integer> strings) {}
23 24
 
24 25
     if (strings is Sequence<String>) {
25 26
         //print(strings.first);
@@ -28,6 +29,7 @@ class Is() {
28 29
     @error if (strings is SimpleContainer<String>) {}
29 30
     @error if (strings is Is.SimpleContainer) {}
30 31
     @error if (strings is Is.SimpleContainer<String>) {}
  32
+    @error if (strings is Is.SimpleContainer<String,Integer>) {}
31 33
 
32 34
     void method<T>() {
33 35
         if (is T strings) {}

0 notes on commit 5dc0ed0

Please sign in to comment.
Something went wrong with that request. Please try again.