| 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 |