OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 | 2 |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 1806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 var tStaticSetters = <JS.Property>[]; | 1817 var tStaticSetters = <JS.Property>[]; |
1818 var tInstanceSetters = <JS.Property>[]; | 1818 var tInstanceSetters = <JS.Property>[]; |
1819 var sNames = <JS.Expression>[]; | 1819 var sNames = <JS.Expression>[]; |
1820 for (MethodDeclaration node in methods) { | 1820 for (MethodDeclaration node in methods) { |
1821 var name = node.name.name; | 1821 var name = node.name.name; |
1822 var element = resolutionMap.elementDeclaredByMethodDeclaration(node); | 1822 var element = resolutionMap.elementDeclaredByMethodDeclaration(node); |
1823 // TODO(vsm): Clean up all the nasty duplication. | 1823 // TODO(vsm): Clean up all the nasty duplication. |
1824 if (node.isAbstract) { | 1824 if (node.isAbstract) { |
1825 continue; | 1825 continue; |
1826 } | 1826 } |
1827 | 1827 if (node.isStatic && |
| 1828 !options.emitMetadata && |
| 1829 (node.isGetter || node.isSetter)) { |
| 1830 continue; |
| 1831 } |
1828 List<JS.Property> tMember; | 1832 List<JS.Property> tMember; |
1829 Function getOverride; | 1833 Function getOverride; |
1830 Function lookup; | 1834 Function lookup; |
1831 Function elementToType; | 1835 Function elementToType; |
1832 if (node.isGetter) { | 1836 if (node.isGetter) { |
1833 elementToType = (ExecutableElement element) => element.type; | 1837 elementToType = (ExecutableElement element) => element.type; |
1834 getOverride = classElem.lookUpInheritedConcreteGetter; | 1838 getOverride = classElem.lookUpInheritedConcreteGetter; |
1835 lookup = classElem.type.lookUpInheritedGetter; | 1839 lookup = classElem.type.lookUpInheritedGetter; |
1836 tMember = node.isStatic ? tStaticGetters : tInstanceGetters; | 1840 tMember = node.isStatic ? tStaticGetters : tInstanceGetters; |
1837 } else if (node.isSetter) { | 1841 } else if (node.isSetter) { |
1838 elementToType = (ExecutableElement element) => element.type; | 1842 elementToType = (ExecutableElement element) => element.type; |
1839 getOverride = classElem.lookUpInheritedConcreteSetter; | 1843 getOverride = classElem.lookUpInheritedConcreteSetter; |
1840 lookup = classElem.type.lookUpInheritedSetter; | 1844 lookup = classElem.type.lookUpInheritedSetter; |
1841 tMember = node.isStatic ? tStaticSetters : tInstanceSetters; | 1845 tMember = node.isStatic ? tStaticSetters : tInstanceSetters; |
1842 } else { | 1846 } else { |
1843 // Method | 1847 // Method |
1844 // Swap in "Object" for parameter types that are covariant overrides. | 1848 // Swap in "Object" for parameter types that are covariant overrides. |
1845 var objectType = context.typeProvider.objectType; | 1849 var objectType = context.typeProvider.objectType; |
1846 elementToType = | 1850 elementToType = |
1847 (MethodElement element) => element.getReifiedType(objectType); | 1851 (MethodElement element) => element.getReifiedType(objectType); |
1848 getOverride = classElem.lookUpInheritedConcreteMethod; | 1852 getOverride = classElem.lookUpInheritedConcreteMethod; |
1849 lookup = classElem.type.lookUpInheritedMethod; | 1853 lookup = classElem.type.lookUpInheritedMethod; |
1850 tMember = node.isStatic ? tStaticMethods : tInstanceMethods; | 1854 tMember = node.isStatic ? tStaticMethods : tInstanceMethods; |
1851 } | 1855 } |
1852 | 1856 |
1853 DartType reifiedType = elementToType(element); | 1857 DartType reifiedType = elementToType(element); |
1854 var type = _emitAnnotatedFunctionType(reifiedType, node.metadata, | |
1855 parameters: node.parameters?.parameters, | |
1856 nameType: options.hoistSignatureTypes, | |
1857 hoistType: options.hoistSignatureTypes, | |
1858 definite: true); | |
1859 | |
1860 // Don't add redundant signatures for inherited methods whose signature | 1858 // Don't add redundant signatures for inherited methods whose signature |
1861 // did not change. If we are not overriding, or if the thing we are | 1859 // did not change. If we are not overriding, or if the thing we are |
1862 // overriding has a different reified type from ourselves, we must | 1860 // overriding has a different reified type from ourselves, we must |
1863 // emit a signature on this class. Otherwise we will inherit the | 1861 // emit a signature on this class. Otherwise we will inherit the |
1864 // signature from the superclass. | 1862 // signature from the superclass. |
1865 var needsSignature = getOverride(name, currentLibrary) == null || | 1863 var needsSignature = getOverride(name, currentLibrary) == null || |
1866 elementToType( | 1864 elementToType( |
1867 lookup(name, library: currentLibrary, thisType: false)) != | 1865 lookup(name, library: currentLibrary, thisType: false)) != |
1868 reifiedType; | 1866 reifiedType; |
1869 | 1867 |
| 1868 var type = _emitAnnotatedFunctionType(reifiedType, node.metadata, |
| 1869 parameters: node.parameters?.parameters, |
| 1870 nameType: options.hoistSignatureTypes, |
| 1871 hoistType: options.hoistSignatureTypes, |
| 1872 definite: true); |
| 1873 |
1870 if (needsSignature) { | 1874 if (needsSignature) { |
1871 var memberName = _declareMemberName(element); | 1875 var memberName = _declareMemberName(element); |
1872 var property = new JS.Property(memberName, type); | 1876 var property = new JS.Property(memberName, type); |
1873 tMember.add(property); | 1877 tMember.add(property); |
1874 // TODO(vsm): Why do we need this? | 1878 // We record the names of static methods seperately so we can |
| 1879 // attach metadata to them individually. |
| 1880 // TODO(leafp): Revisit this. |
1875 if (node.isStatic && !node.isGetter && !node.isSetter) { | 1881 if (node.isStatic && !node.isGetter && !node.isSetter) { |
1876 sNames.add(memberName); | 1882 sNames.add(memberName); |
1877 } | 1883 } |
1878 } | 1884 } |
1879 } | 1885 } |
1880 | 1886 |
1881 var tInstanceFields = <JS.Property>[]; | 1887 var tInstanceFields = <JS.Property>[]; |
1882 var tStaticFields = <JS.Property>[]; | 1888 var tStaticFields = <JS.Property>[]; |
1883 for (FieldDeclaration node in fields) { | 1889 for (FieldDeclaration node in fields) { |
1884 for (VariableDeclaration field in node.fields.variables) { | 1890 if (!node.isStatic || options.emitMetadata) { |
1885 var element = field.element as FieldElement; | 1891 for (VariableDeclaration field in node.fields.variables) { |
1886 var memberName = _declareMemberName(element.getter); | 1892 var element = field.element as FieldElement; |
1887 var type = _emitAnnotatedType(element.type, node.metadata); | 1893 var memberName = _declareMemberName(element.getter); |
1888 var property = new JS.Property(memberName, type); | 1894 var type = _emitAnnotatedType(element.type, node.metadata); |
1889 (node.isStatic ? tStaticFields : tInstanceFields).add(property); | 1895 var property = new JS.Property(memberName, type); |
| 1896 (node.isStatic ? tStaticFields : tInstanceFields).add(property); |
| 1897 } |
1890 } | 1898 } |
1891 } | 1899 } |
1892 | 1900 |
1893 var tCtors = <JS.Property>[]; | 1901 var tCtors = <JS.Property>[]; |
1894 for (ConstructorDeclaration node in ctors) { | 1902 if (options.emitMetadata) { |
1895 var memberName = _constructorName(node.element); | 1903 for (ConstructorDeclaration node in ctors) { |
1896 var element = resolutionMap.elementDeclaredByConstructorDeclaration(node); | 1904 var memberName = _constructorName(node.element); |
1897 var type = _emitAnnotatedFunctionType(element.type, node.metadata, | 1905 var element = |
1898 parameters: node.parameters.parameters, | 1906 resolutionMap.elementDeclaredByConstructorDeclaration(node); |
1899 nameType: options.hoistSignatureTypes, | 1907 var type = _emitAnnotatedFunctionType(element.type, node.metadata, |
1900 hoistType: options.hoistSignatureTypes, | 1908 parameters: node.parameters.parameters, |
1901 definite: true); | 1909 nameType: options.hoistSignatureTypes, |
1902 var property = new JS.Property(memberName, type); | 1910 hoistType: options.hoistSignatureTypes, |
1903 tCtors.add(property); | 1911 definite: true); |
| 1912 var property = new JS.Property(memberName, type); |
| 1913 tCtors.add(property); |
| 1914 } |
1904 } | 1915 } |
1905 | |
1906 var sigFields = <JS.Property>[]; | 1916 var sigFields = <JS.Property>[]; |
1907 if (!tCtors.isEmpty) { | 1917 if (!tCtors.isEmpty) { |
1908 sigFields.add(_buildSignatureField('constructors', tCtors)); | 1918 sigFields.add(_buildSignatureField('constructors', tCtors)); |
1909 } | 1919 } |
1910 if (!tInstanceFields.isEmpty) { | 1920 if (!tInstanceFields.isEmpty) { |
1911 sigFields.add(_buildSignatureField('fields', tInstanceFields)); | 1921 sigFields.add(_buildSignatureField('fields', tInstanceFields)); |
1912 } | 1922 } |
1913 if (!tInstanceGetters.isEmpty) { | 1923 if (!tInstanceGetters.isEmpty) { |
1914 sigFields.add(_buildSignatureField('getters', tInstanceGetters)); | 1924 sigFields.add(_buildSignatureField('getters', tInstanceGetters)); |
1915 } | 1925 } |
1916 if (!tInstanceSetters.isEmpty) { | 1926 if (!tInstanceSetters.isEmpty) { |
1917 sigFields.add(_buildSignatureField('setters', tInstanceSetters)); | 1927 sigFields.add(_buildSignatureField('setters', tInstanceSetters)); |
1918 } | 1928 } |
1919 if (!tInstanceMethods.isEmpty) { | 1929 if (!tInstanceMethods.isEmpty) { |
1920 sigFields.add(_buildSignatureField('methods', tInstanceMethods)); | 1930 sigFields.add(_buildSignatureField('methods', tInstanceMethods)); |
1921 } | 1931 } |
1922 if (!tStaticFields.isEmpty) { | 1932 if (!tStaticFields.isEmpty) { |
1923 sigFields.add(_buildSignatureField('sfields', tStaticFields)); | 1933 sigFields.add(_buildSignatureField('sfields', tStaticFields)); |
1924 } | 1934 } |
1925 if (!tStaticGetters.isEmpty) { | 1935 if (!tStaticGetters.isEmpty) { |
1926 sigFields.add(_buildSignatureField('sgetters', tStaticGetters)); | 1936 sigFields.add(_buildSignatureField('sgetters', tStaticGetters)); |
1927 } | 1937 } |
1928 if (!tStaticSetters.isEmpty) { | 1938 if (!tStaticSetters.isEmpty) { |
1929 sigFields.add(_buildSignatureField('ssetters', tStaticSetters)); | 1939 sigFields.add(_buildSignatureField('ssetters', tStaticSetters)); |
1930 } | 1940 } |
1931 if (!tStaticMethods.isEmpty) { | 1941 if (!tStaticMethods.isEmpty) { |
1932 assert(!sNames.isEmpty); | 1942 assert(!sNames.isEmpty); |
1933 // TODO(vsm): Why do we need this names field? | 1943 // Emit names so that we can lazily attach metadata to statics |
| 1944 // TODO(leafp): revisit this strategy |
1934 var aNames = new JS.Property( | 1945 var aNames = new JS.Property( |
1935 _propertyName('names'), new JS.ArrayInitializer(sNames)); | 1946 _propertyName('names'), new JS.ArrayInitializer(sNames)); |
1936 sigFields.add(_buildSignatureField('statics', tStaticMethods)); | 1947 sigFields.add(_buildSignatureField('statics', tStaticMethods)); |
1937 sigFields.add(aNames); | 1948 sigFields.add(aNames); |
1938 } | 1949 } |
1939 if (!sigFields.isEmpty || extensions.isNotEmpty) { | 1950 if (!sigFields.isEmpty || extensions.isNotEmpty) { |
1940 var sig = new JS.ObjectInitializer(sigFields); | 1951 var sig = new JS.ObjectInitializer(sigFields); |
1941 body.add(_callHelperStatement('setSignature(#, #);', [className, sig])); | 1952 body.add(_callHelperStatement('setSignature(#, #);', [className, sig])); |
1942 } | 1953 } |
1943 // Add static property dart._runtimeType to Object. | 1954 // Add static property dart._runtimeType to Object. |
(...skipping 3946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5901 if (targetIdentifier.staticElement is! PrefixElement) return false; |
5891 var prefix = targetIdentifier.staticElement as PrefixElement; | 5902 var prefix = targetIdentifier.staticElement as PrefixElement; |
5892 | 5903 |
5893 // The library the prefix is referring to must come from a deferred import. | 5904 // The library the prefix is referring to must come from a deferred import. |
5894 var containingLibrary = resolutionMap | 5905 var containingLibrary = resolutionMap |
5895 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 5906 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
5896 .library; | 5907 .library; |
5897 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5908 var imports = containingLibrary.getImportsWithPrefix(prefix); |
5898 return imports.length == 1 && imports[0].isDeferred; | 5909 return imports.length == 1 && imports[0].isDeferred; |
5899 } | 5910 } |
OLD | NEW |