Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(588)

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10996039: Bring type variables into static scope, but produce compile-time error when they are used. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Produce warning and dynamic type error instead of compile-time error. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 abstract class TreeElements { 5 abstract class TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 DartType getType(TypeAnnotation annotation); 8 DartType getType(TypeAnnotation annotation);
9 bool isParameterChecked(Element element); 9 bool isParameterChecked(Element element);
10 } 10 }
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 } else if (element.isClass()) { 1042 } else if (element.isClass()) {
1043 ClassElement cls = element; 1043 ClassElement cls = element;
1044 cls.ensureResolved(compiler); 1044 cls.ensureResolved(compiler);
1045 Link<DartType> arguments = 1045 Link<DartType> arguments =
1046 resolveTypeArguments(node, cls.typeVariables, scope, 1046 resolveTypeArguments(node, cls.typeVariables, scope,
1047 onFailure, whenResolved); 1047 onFailure, whenResolved);
1048 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { 1048 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) {
1049 // Use the canonical type if it has no type parameters. 1049 // Use the canonical type if it has no type parameters.
1050 type = cls.computeType(compiler); 1050 type = cls.computeType(compiler);
1051 } else { 1051 } else {
1052 type = new InterfaceType(cls, arguments); 1052 bool isMalformedType = false;
1053 for (Link<DartType> link = arguments;
1054 !link.isEmpty();
1055 link = link.tail) {
1056 DartType dtype = link.head;
karlklose 2012/10/10 07:19:33 dtype -> type. (The class is only called DartType
1057 if (dtype is MalformedType) {
1058 isMalformedType = true;
1059 break;
1060 }
1061 }
1062 if (isMalformedType) {
1063 type = new MalformedType(
1064 new MalformedTypeElement(node, scope.element));
1065 } else {
1066 type = new InterfaceType(cls, arguments);
1067 }
1053 } 1068 }
1054 } else if (element.isTypedef()) { 1069 } else if (element.isTypedef()) {
1055 TypedefElement typdef = element; 1070 TypedefElement typdef = element;
1056 // TODO(ahe): Should be [ensureResolved]. 1071 // TODO(ahe): Should be [ensureResolved].
1057 compiler.resolveTypedef(typdef); 1072 compiler.resolveTypedef(typdef);
1058 typdef.computeType(compiler); 1073 typdef.computeType(compiler);
1059 Link<DartType> arguments = resolveTypeArguments( 1074 Link<DartType> arguments = resolveTypeArguments(
1060 node, typdef.typeVariables, 1075 node, typdef.typeVariables,
1061 scope, onFailure, whenResolved); 1076 scope, onFailure, whenResolved);
1062 if (typdef.typeVariables.isEmpty() && arguments.isEmpty()) { 1077 if (typdef.typeVariables.isEmpty() && arguments.isEmpty()) {
1063 // Return the canonical type if it has no type parameters. 1078 // Return the canonical type if it has no type parameters.
1064 type = typdef.computeType(compiler); 1079 type = typdef.computeType(compiler);
1065 } else { 1080 } else {
1066 type = new TypedefType(typdef, arguments); 1081 type = new TypedefType(typdef, arguments);
1067 } 1082 }
1068 } else if (element.isTypeVariable()) { 1083 } else if (element.isTypeVariable()) {
1069 type = element.computeType(compiler); 1084 if (scope.inStaticContext) {
1085 onFailure(node, MessageKind.CANNOT_ACCESS_TYPE_VARIABLE_IN_STATIC_CONT EXT, [element.name]);
karlklose 2012/10/10 07:19:33 Long line.
1086 type = new MalformedType(
1087 new MalformedTypeElement(node, scope.element));
1088 } else {
1089 type = element.computeType(compiler);
1090 }
1070 } else { 1091 } else {
1071 compiler.cancel("unexpected element kind ${element.kind}", 1092 compiler.cancel("unexpected element kind ${element.kind}",
1072 node: node); 1093 node: node);
1073 } 1094 }
1074 } 1095 }
1075 whenResolved(node, type); 1096 whenResolved(node, type);
1076 return type; 1097 return type;
1077 } 1098 }
1078 1099
1079 Link<DartType> resolveTypeArguments(TypeAnnotation node, 1100 Link<DartType> resolveTypeArguments(TypeAnnotation node,
(...skipping 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after
2875 } else if (e.kind !== ElementKind.CLASS && e.kind !== ElementKind.PREFIX) { 2896 } else if (e.kind !== ElementKind.CLASS && e.kind !== ElementKind.PREFIX) {
2876 error(node, MessageKind.NOT_A_TYPE, [name]); 2897 error(node, MessageKind.NOT_A_TYPE, [name]);
2877 } 2898 }
2878 return e; 2899 return e;
2879 } 2900 }
2880 } 2901 }
2881 2902
2882 abstract class Scope { 2903 abstract class Scope {
2883 final Element element; 2904 final Element element;
2884 final Scope parent; 2905 final Scope parent;
2906 bool get inStaticContext => false;
2885 2907
2886 Scope(this.parent, this.element); 2908 Scope(this.parent, this.element);
2887 abstract Element add(Element element); 2909 abstract Element add(Element element);
2888 2910
2889 Element lookup(SourceString name) { 2911 Element lookup(SourceString name) {
2890 Element result = localLookup(name); 2912 Element result = localLookup(name);
2891 if (result != null) return result; 2913 if (result != null) return result;
2892 return parent.lookup(name); 2914 return parent.lookup(name);
2893 } 2915 }
2894 2916
2895 Element lexicalLookup(SourceString name) { 2917 Element lexicalLookup(SourceString name) {
2896 Element result = localLookup(name); 2918 Element result = localLookup(name);
2897 if (result != null) return result; 2919 if (result != null) return result;
2898 return parent.lexicalLookup(name); 2920 return parent.lexicalLookup(name);
2899 } 2921 }
2900 2922
2901 abstract Element localLookup(SourceString name); 2923 abstract Element localLookup(SourceString name);
2902 } 2924 }
2903 2925
2904 class VariableScope extends Scope { 2926 class VariableScope extends Scope {
2905 VariableScope(parent, element) : super(parent, element); 2927 VariableScope(parent, element) : super(parent, element);
2906 2928
2907 Element add(Element newElement) { 2929 Element add(Element newElement) {
2908 throw "Cannot add element to VariableScope"; 2930 throw "Cannot add element to VariableScope";
2909 } 2931 }
2910 2932
2911 Element localLookup(SourceString name) => null; 2933 Element localLookup(SourceString name) => null;
2912 2934
2913 String toString() => '$element > $parent'; 2935 String toString() => '$element > $parent';
2936
2937 bool get inStaticContext => element.inStaticContext();//parent.inStaticContext ();
karlklose 2012/10/10 07:19:33 Remove code in comment.
2914 } 2938 }
2915 2939
2916 /** 2940 /**
2917 * [TypeDeclarationScope] defines the outer scope of a type declaration in 2941 * [TypeDeclarationScope] defines the outer scope of a type declaration in
2918 * which the declared type variables and the entities in the enclosing scope are 2942 * which the declared type variables and the entities in the enclosing scope are
2919 * available but where declared and inherited members are not available. This 2943 * available but where declared and inherited members are not available. This
2920 * scope is only used for class/interface declarations during resolution of the 2944 * scope is only used for class/interface declarations during resolution of the
2921 * class hierarchy. In all other cases [ClassScope] is used. 2945 * class hierarchy. In all other cases [ClassScope] is used.
2922 */ 2946 */
2923 class TypeDeclarationScope extends Scope { 2947 class TypeDeclarationScope extends Scope {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2961 2985
2962 Element add(Element newElement) { 2986 Element add(Element newElement) {
2963 if (elements.containsKey(newElement.name)) { 2987 if (elements.containsKey(newElement.name)) {
2964 return elements[newElement.name]; 2988 return elements[newElement.name];
2965 } 2989 }
2966 elements[newElement.name] = newElement; 2990 elements[newElement.name] = newElement;
2967 return newElement; 2991 return newElement;
2968 } 2992 }
2969 2993
2970 String toString() => '$element${elements.getKeys()}'; 2994 String toString() => '$element${elements.getKeys()}';
2995
2996 bool get inStaticContext => parent.inStaticContext;
2971 } 2997 }
2972 2998
2973 class BlockScope extends MethodScope { 2999 class BlockScope extends MethodScope {
2974 BlockScope(Scope parent) : super(parent, parent.element); 3000 BlockScope(Scope parent) : super(parent, parent.element);
2975 3001
2976 String toString() => 'block${elements.getKeys()}'; 3002 String toString() => 'block${elements.getKeys()}';
2977 } 3003 }
2978 3004
2979 /** 3005 /**
2980 * [ClassScope] defines the inner scope of a class/interface declaration in 3006 * [ClassScope] defines the inner scope of a class/interface declaration in
2981 * which declared members, declared type variables, entities in the enclosing 3007 * which declared members, declared type variables, entities in the enclosing
2982 * scope and inherited members are available, in the given order. 3008 * scope and inherited members are available, in the given order.
2983 */ 3009 */
2984 class ClassScope extends TypeDeclarationScope { 3010 class ClassScope extends TypeDeclarationScope {
2985 bool inStaticContext = false; 3011 bool inStaticContext = false;
2986 3012
2987 ClassScope(Scope parentScope, ClassElement element) 3013 ClassScope(Scope parentScope, ClassElement element)
2988 : super(parentScope, element) { 3014 : super(parentScope, element) {
2989 assert(parent !== null); 3015 assert(parent !== null);
2990 } 3016 }
2991 3017
2992 Element localLookup(SourceString name) { 3018 Element localLookup(SourceString name) {
2993 ClassElement cls = element; 3019 ClassElement cls = element;
2994 Element result = cls.lookupLocalMember(name); 3020 Element result = cls.lookupLocalMember(name);
2995 if (result !== null) return result; 3021 if (result !== null) return result;
2996 if (!inStaticContext) { 3022 result = super.localLookup(name);
2997 // If not in a static context, we can lookup in the
2998 // TypeDeclaration scope, which contains the type variables of
2999 // the class.
3000 result = super.localLookup(name);
3001 }
3002 return result; 3023 return result;
3003 } 3024 }
3004 3025
3005 Element lookup(SourceString name) { 3026 Element lookup(SourceString name) {
3006 Element result = localLookup(name); 3027 Element result = localLookup(name);
3007 if (result !== null) return result; 3028 if (result !== null) return result;
3008 result = parent.lookup(name); 3029 result = parent.lookup(name);
3009 if (result !== null) return result; 3030 if (result !== null) return result;
3010 ClassElement cls = element; 3031 ClassElement cls = element;
3011 return cls.lookupSuperMember(name); 3032 return cls.lookupSuperMember(name);
(...skipping 16 matching lines...) Expand all
3028 ClassElement origin, ClassElement this.patch) 3049 ClassElement origin, ClassElement this.patch)
3029 : super(parentScope, origin) { 3050 : super(parentScope, origin) {
3030 assert(parent !== null); 3051 assert(parent !== null);
3031 } 3052 }
3032 3053
3033 Element localLookup(SourceString name) { 3054 Element localLookup(SourceString name) {
3034 Element result = patch.lookupLocalMember(name); 3055 Element result = patch.lookupLocalMember(name);
3035 if (result !== null) return result; 3056 if (result !== null) return result;
3036 result = origin.lookupLocalMember(name); 3057 result = origin.lookupLocalMember(name);
3037 if (result !== null) return result; 3058 if (result !== null) return result;
3038 if (!inStaticContext) { 3059 result = super.localLookup(name);
3039 // If not in a static context, we can lookup in the 3060 if (result !== null) return result;
3040 // TypeDeclaration scope, which contains the type variables of
3041 // the class.
3042 result = super.localLookup(name);
3043 if (result !== null) return result;
3044 }
3045 result = parent.lookup(name); 3061 result = parent.lookup(name);
3046 if (result !== null) return result; 3062 if (result !== null) return result;
3047 return result; 3063 return result;
3048 } 3064 }
3049 3065
3050 Element lookup(SourceString name) { 3066 Element lookup(SourceString name) {
3051 Element result = localLookup(name); 3067 Element result = localLookup(name);
3052 if (result !== null) return result; 3068 if (result !== null) return result;
3053 // TODO(johnniwinther): Should we support patch lookup on supertypes? 3069 // TODO(johnniwinther): Should we support patch lookup on supertypes?
3054 return origin.lookupSuperMember(name); 3070 return origin.lookupSuperMember(name);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3136 return result; 3152 return result;
3137 } 3153 }
3138 Element lookup(SourceString name) => localLookup(name); 3154 Element lookup(SourceString name) => localLookup(name);
3139 Element lexicalLookup(SourceString name) => localLookup(name); 3155 Element lexicalLookup(SourceString name) => localLookup(name);
3140 3156
3141 Element add(Element newElement) { 3157 Element add(Element newElement) {
3142 throw "Cannot add an element in a patch library scope"; 3158 throw "Cannot add an element in a patch library scope";
3143 } 3159 }
3144 String toString() => 'PatchLibraryScope($origin,$patch)'; 3160 String toString() => 'PatchLibraryScope($origin,$patch)';
3145 } 3161 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/js_backend/namer.dart ('k') | lib/compiler/implementation/typechecker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698