Chromium Code Reviews| OLD | NEW |
|---|---|
| 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(Node node); | 8 DartType getType(Node node); |
| 9 bool isParameterChecked(Element element); | 9 bool isParameterChecked(Element element); |
| 10 } | 10 } |
| (...skipping 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1898 includeSuperMembers: true); | 1898 includeSuperMembers: true); |
| 1899 return null; | 1899 return null; |
| 1900 } | 1900 } |
| 1901 | 1901 |
| 1902 /** | 1902 /** |
| 1903 * Try to resolve the constructor that is referred to by [node]. | 1903 * Try to resolve the constructor that is referred to by [node]. |
| 1904 * Note: this function may return an ErroneousFunctionElement instead of | 1904 * Note: this function may return an ErroneousFunctionElement instead of |
| 1905 * [null], if there is no corresponding constructor, class or library. | 1905 * [null], if there is no corresponding constructor, class or library. |
| 1906 */ | 1906 */ |
| 1907 FunctionElement resolveConstructor(NewExpression node) { | 1907 FunctionElement resolveConstructor(NewExpression node) { |
| 1908 // Resolve the constructor that [node] refers to. | 1908 return node.accept(new ConstructorResolver(compiler, this)); |
| 1909 ConstructorResolver visitor = | |
| 1910 new ConstructorResolver(compiler, this, node.isConst()); | |
| 1911 FunctionElement constructor = node.accept(visitor); | |
| 1912 // Try to resolve the type that the new-expression constructs. | |
| 1913 TypeAnnotation annotation = node.send.getTypeAnnotation(); | |
| 1914 if (Elements.isUnresolved(constructor)) { | |
| 1915 // Resolve the type arguments. We cannot create a type and check the | |
| 1916 // number of type arguments for this annotation, because we do not know | |
| 1917 // the element. | |
| 1918 Link arguments = const Link<Node>(); | |
| 1919 if (annotation.typeArguments != null) { | |
| 1920 arguments = annotation.typeArguments.nodes; | |
| 1921 } | |
| 1922 for (Node argument in arguments) { | |
| 1923 resolveTypeRequired(argument); | |
| 1924 } | |
| 1925 } else { | |
| 1926 // Resolve and store the type this annotation resolves to. The type | |
| 1927 // is used in the backend, e.g., for creating runtime type information. | |
| 1928 // TODO(karlklose): This will resolve the class element again. Refactor | |
| 1929 // so we can use the TypeResolver. | |
| 1930 resolveTypeRequired(annotation); | |
| 1931 } | |
| 1932 return constructor; | |
| 1933 } | 1909 } |
| 1934 | 1910 |
| 1935 DartType resolveTypeRequired(TypeAnnotation node) { | 1911 DartType resolveTypeRequired(TypeAnnotation node) { |
| 1936 bool old = typeRequired; | 1912 bool old = typeRequired; |
| 1937 typeRequired = true; | 1913 typeRequired = true; |
| 1938 DartType result = resolveTypeAnnotation(node); | 1914 DartType result = resolveTypeAnnotation(node); |
| 1939 typeRequired = old; | 1915 typeRequired = old; |
| 1940 return result; | 1916 return result; |
| 1941 } | 1917 } |
| 1942 | 1918 |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2833 | 2809 |
| 2834 // TODO(ahe): This is temporary. | 2810 // TODO(ahe): This is temporary. |
| 2835 ClassElement get currentClass { | 2811 ClassElement get currentClass { |
| 2836 return enclosingElement.isMember() | 2812 return enclosingElement.isMember() |
| 2837 ? enclosingElement.getEnclosingClass() : null; | 2813 ? enclosingElement.getEnclosingClass() : null; |
| 2838 } | 2814 } |
| 2839 } | 2815 } |
| 2840 | 2816 |
| 2841 class ConstructorResolver extends CommonResolverVisitor<Element> { | 2817 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 2842 final ResolverVisitor resolver; | 2818 final ResolverVisitor resolver; |
| 2843 // TODO(ngeoffray): have this context at the call site. | 2819 bool inConstContext = false; |
| 2844 final bool inConstContext; | 2820 DartType type; |
|
Johnni Winther
2012/10/22 09:41:38
Document the semantics and usage of [isConstContex
| |
| 2845 | 2821 |
| 2846 ConstructorResolver(Compiler compiler, | 2822 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 2847 this.resolver, | |
| 2848 this.inConstContext) | |
| 2849 : super(compiler); | |
| 2850 | 2823 |
| 2851 visitNode(Node node) { | 2824 visitNode(Node node) { |
| 2852 throw 'not supported'; | 2825 throw 'not supported'; |
| 2853 } | 2826 } |
| 2854 | 2827 |
| 2855 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, | 2828 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| 2856 SourceString targetName, MessageKind kind, | 2829 SourceString targetName, MessageKind kind, |
| 2857 List arguments) { | 2830 List arguments) { |
| 2858 if (inConstContext) { | 2831 if (inConstContext) { |
| 2859 error(diagnosticNode, kind, arguments); | 2832 error(diagnosticNode, kind, arguments); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2892 new SourceString(fullConstructorName), | 2865 new SourceString(fullConstructorName), |
| 2893 MessageKind.CANNOT_FIND_CONSTRUCTOR, | 2866 MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 2894 [fullConstructorName]); | 2867 [fullConstructorName]); |
| 2895 } else if (inConstContext && !result.modifiers.isConst()) { | 2868 } else if (inConstContext && !result.modifiers.isConst()) { |
| 2896 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 2869 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 2897 } | 2870 } |
| 2898 return result; | 2871 return result; |
| 2899 } | 2872 } |
| 2900 | 2873 |
| 2901 visitNewExpression(NewExpression node) { | 2874 visitNewExpression(NewExpression node) { |
| 2875 inConstContext = node.isConst(); | |
| 2902 Node selector = node.send.selector; | 2876 Node selector = node.send.selector; |
| 2903 Element e = visit(selector); | 2877 Element e = visit(selector); |
| 2904 if (!Elements.isUnresolved(e) && identical(e.kind, ElementKind.CLASS)) { | 2878 if (!Elements.isUnresolved(e) && identical(e.kind, ElementKind.CLASS)) { |
| 2905 ClassElement cls = e; | 2879 ClassElement cls = e; |
| 2906 cls.ensureResolved(compiler); | 2880 cls.ensureResolved(compiler); |
| 2907 if (cls.isInterface() && (cls.defaultClass == null)) { | 2881 if (cls.isInterface() && (cls.defaultClass == null)) { |
| 2908 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 2882 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| 2909 } | 2883 } |
| 2910 e = lookupConstructor(cls, selector, const SourceString('')); | 2884 e = lookupConstructor(cls, selector, const SourceString('')); |
| 2911 } | 2885 } |
| 2886 if (type == null) { | |
|
Johnni Winther
2012/10/22 09:30:31
Document where [type] has been set.
| |
| 2887 type = e.getEnclosingClass().computeType(compiler); | |
|
Johnni Winther
2012/10/22 09:41:38
I don't think this is the right type. For 'new Obj
| |
| 2888 } | |
| 2889 resolver.mapping.setType(node, type); | |
| 2912 return e; | 2890 return e; |
| 2913 } | 2891 } |
| 2914 | 2892 |
| 2915 visitTypeAnnotation(TypeAnnotation node) { | 2893 visitTypeAnnotation(TypeAnnotation node) { |
| 2916 return visit(node.typeName); | 2894 assert(invariant(node, type == null)); |
| 2895 type = resolver.resolveTypeRequired(node); | |
| 2896 return resolver.mapping[node]; | |
| 2917 } | 2897 } |
| 2918 | 2898 |
| 2919 visitSend(Send node) { | 2899 visitSend(Send node) { |
| 2920 Element e = visit(node.receiver); | 2900 Element e = visit(node.receiver); |
| 2921 if (Elements.isUnresolved(e)) return e; | 2901 if (Elements.isUnresolved(e)) return e; |
| 2922 Identifier name = node.selector.asIdentifier(); | 2902 Identifier name = node.selector.asIdentifier(); |
| 2923 if (name == null) internalError(node.selector, 'unexpected node'); | 2903 if (name == null) internalError(node.selector, 'unexpected node'); |
| 2924 | 2904 |
| 2925 if (identical(e.kind, ElementKind.CLASS)) { | 2905 if (identical(e.kind, ElementKind.CLASS)) { |
| 2926 ClassElement cls = e; | 2906 ClassElement cls = e; |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3190 return result; | 3170 return result; |
| 3191 } | 3171 } |
| 3192 Element lookup(SourceString name) => localLookup(name); | 3172 Element lookup(SourceString name) => localLookup(name); |
| 3193 Element lexicalLookup(SourceString name) => localLookup(name); | 3173 Element lexicalLookup(SourceString name) => localLookup(name); |
| 3194 | 3174 |
| 3195 Element add(Element newElement) { | 3175 Element add(Element newElement) { |
| 3196 throw "Cannot add an element in a patch library scope"; | 3176 throw "Cannot add an element in a patch library scope"; |
| 3197 } | 3177 } |
| 3198 String toString() => 'PatchLibraryScope($origin,$patch)'; | 3178 String toString() => 'PatchLibraryScope($origin,$patch)'; |
| 3199 } | 3179 } |
| OLD | NEW |