// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library vm.metadata.procedure_attributes; import 'package:kernel/ast.dart'; /// Metadata for annotating procedures with various attributes. class ProcedureAttributesMetadata { static const int kInvalidSelectorId = 0; final bool methodOrSetterCalledDynamically; final bool getterCalledDynamically; final bool hasThisUses; final bool hasNonThisUses; final bool hasTearOffUses; final int methodOrSetterSelectorId; final int getterSelectorId; const ProcedureAttributesMetadata( {this.methodOrSetterCalledDynamically: true, this.getterCalledDynamically: true, this.hasThisUses: true, this.hasNonThisUses: true, this.hasTearOffUses: true, this.methodOrSetterSelectorId: kInvalidSelectorId, this.getterSelectorId: kInvalidSelectorId}); const ProcedureAttributesMetadata.noDynamicUses() : this( methodOrSetterCalledDynamically: false, getterCalledDynamically: false); @override String toString() { final attrs = []; if (!methodOrSetterCalledDynamically) { attrs.add('methodOrSetterCalledDynamically:false'); } if (!getterCalledDynamically) attrs.add('getterCalledDynamically:false'); if (!hasThisUses) attrs.add('hasThisUses:false'); if (!hasNonThisUses) attrs.add('hasNonThisUses:false'); if (!hasTearOffUses) attrs.add('hasTearOffUses:false'); if (methodOrSetterSelectorId != kInvalidSelectorId) { attrs.add('methodOrSetterSelectorId:$methodOrSetterSelectorId'); } if (getterSelectorId != kInvalidSelectorId) { attrs.add('getterSelectorId:$getterSelectorId'); } return attrs.join(','); } } /// Repository for [ProcedureAttributesMetadata]. class ProcedureAttributesMetadataRepository extends MetadataRepository { static const int kMethodOrSetterCalledDynamicallyBit = 1 << 0; static const int kNonThisUsesBit = 1 << 1; static const int kTearOffUsesBit = 1 << 2; static const int kThisUsesBit = 1 << 3; static const int kGetterCalledDynamicallyBit = 1 << 4; static const repositoryTag = 'vm.procedure-attributes.metadata'; @override final String tag = repositoryTag; @override final Map mapping = {}; int _getFlags(ProcedureAttributesMetadata metadata) { int flags = 0; if (metadata.methodOrSetterCalledDynamically) { flags |= kMethodOrSetterCalledDynamicallyBit; } if (metadata.getterCalledDynamically) { flags |= kGetterCalledDynamicallyBit; } if (metadata.hasThisUses) { flags |= kThisUsesBit; } if (metadata.hasNonThisUses) { flags |= kNonThisUsesBit; } if (metadata.hasTearOffUses) { flags |= kTearOffUsesBit; } return flags; } @override void writeToBinary( ProcedureAttributesMetadata metadata, Node node, BinarySink sink) { sink.writeByte(_getFlags(metadata)); sink.writeUInt30(metadata.methodOrSetterSelectorId); sink.writeUInt30(metadata.getterSelectorId); } @override ProcedureAttributesMetadata readFromBinary(Node node, BinarySource source) { final int flags = source.readByte(); final bool methodOrSetterCalledDynamically = (flags & kMethodOrSetterCalledDynamicallyBit) != 0; final bool getterCalledDynamically = (flags & kGetterCalledDynamicallyBit) != 0; final bool hasThisUses = (flags & kThisUsesBit) != 0; final bool hasNonThisUses = (flags & kNonThisUsesBit) != 0; final bool hasTearOffUses = (flags & kTearOffUsesBit) != 0; final int methodOrSetterSelectorId = source.readUInt30(); final int getterSelectorId = source.readUInt30(); return new ProcedureAttributesMetadata( methodOrSetterCalledDynamically: methodOrSetterCalledDynamically, getterCalledDynamically: getterCalledDynamically, hasThisUses: hasThisUses, hasNonThisUses: hasNonThisUses, hasTearOffUses: hasTearOffUses, methodOrSetterSelectorId: methodOrSetterSelectorId, getterSelectorId: getterSelectorId); } }