text:
namespace Slang
{
    class Module;
    class Name;
    class Session;
    class Substitutions;
    class SyntaxVisitor;
    class FuncDecl;
    class Layout;

    struct IExprVisitor;
    struct IDeclVisitor;
    struct IModifierVisitor;
    struct IStmtVisitor;
    struct ITypeVisitor;
    struct IValVisitor;

    class Parser;
    class SyntaxNode;

    class Decl;
    struct QualType;
    class Type;
    struct TypeExp;
    class Val;

    class NodeBase;

    template <typename T>
    T* as(NodeBase* node);

    template <typename T>
    const T* as(const NodeBase* node);

    void printDiagnosticArg(StringBuilder& sb, Decl* decl);
    void printDiagnosticArg(StringBuilder& sb, Type* type);
    void printDiagnosticArg(StringBuilder& sb, TypeExp const& type);
    void printDiagnosticArg(StringBuilder& sb, QualType const& type);
    void printDiagnosticArg(StringBuilder& sb, Val* val);

    class SyntaxNode;
    SourceLoc getDiagnosticPos(SyntaxNode const* syntax);
    SourceLoc getDiagnosticPos(TypeExp const& typeExp);

    typedef NodeBase* (*SyntaxParseCallback)(Parser* parser, void* userData);

    typedef unsigned int ConversionCost;
    enum : ConversionCost
    {
        // No conversion at all
        kConversionCost_None = 0,

        // Conversion from a buffer to the type it carries needs to add a minimal
        // extra cost, just so we can distinguish an overload on `ConstantBuffer<Foo>`
        // from one on `Foo`
        kConversionCost_ImplicitDereference = 10,

        // Conversions based on explicit sub-typing relationships are the cheapest
        //
        // TODO(tfoley): We will eventually need a discipline for ranking
        // when two up-casts are comparable.
        kConversionCost_CastToInterface = 50,

        // Conversion that is lossless and keeps the "kind" of the value the same
        kConversionCost_RankPromotion = 150,
        kConversionCost_NoneToOptional = 150,
        kConversionCost_ValToOptional = 150,
        kConversionCost_NullPtrToPtr = 150,
        kConversionCost_PtrToVoidPtr = 150,

        // Conversions that are lossless, but change "kind"
        kConversionCost_UnsignedToSignedPromotion = 200,

        // Conversion from signed->unsigned integer of same or greater size
        kConversionCost_SignedToUnsignedConversion = 300,

        // Cost of converting an integer to a floating-point type
        kConversionCost_IntegerToFloatConversion = 400,

        // Cost of converting a pointer to bool
        kConversionCost_PtrToBool = 400,

        // Default case (usable for user-defined conversions)
        kConversionCost_Default = 500,

        // Catch-all for conversions that should be discouraged
        // (i.e., that really shouldn't be made implicitly)
        //
        // TODO: make these conversions not be allowed implicitly in "Slang mode"
        kConversionCost_GeneralConversion = 900,

        // This is the cost of an explicit conversion, which should
        // not actually be performed.
        kConversionCost_Explicit = 90000,

        // Additional conversion cost to add when promoting from a scalar to
        // a vector (this will be added to the cost, if any, of converting
        // the element type of the vector)
        kConversionCost_ScalarToVector = 1,

        // Conversion is impossible
        kConversionCost_Impossible = 0xFFFFFFFF,
    };

    enum class ImageFormat
    {
#define FORMAT(NAME, OTHER) NAME,
#include "slang-image-format-defs.h"
    };

    struct ImageFormatInfo
    {
        SlangScalarType scalarType;         ///< If image format is not made up of channels of set sizes this will be SLANG_SCALAR_TYPE_NONE
        uint8_t channelCount;               ///< The number of channels
        uint8_t sizeInBytes;                ///< Size in bytes
        UnownedStringSlice name;            ///< The name associated with this type. NOTE! Currently these names *are* the GLSL format names.
    };

    const ImageFormatInfo& getImageFormatInfo(ImageFormat format);

    bool findImageFormatByName(char const* name, ImageFormat* outFormat);
    char const* getGLSLNameForImageFormat(ImageFormat format);

    // TODO(tfoley): We should ditch this enumeration
    // and just use the IR opcodes that represent these
    // types directly. The one major complication there
    // is that the order of the enum values currently
    // matters, since it determines promotion rank.
    // We either need to keep that restriction, or
    // look up promotion rank by some other means.
    //

    class Decl;
    class Val;

    // Helper type for pairing up a name and the location where it appeared
    struct NameLoc
    {
        Name*       name;
        SourceLoc   loc;

        NameLoc()
            : name(nullptr)
        {}

        explicit NameLoc(Name* inName)
            : name(inName)
        {}

        NameLoc(Name* inName, SourceLoc inLoc)
            : name(inName)
            , loc(inLoc)
        {}

        NameLoc(Token const& token)
            : name(token.getNameOrNull())
            , loc(token.getLoc())
        {}
    };

    struct StringSliceLoc
    {
        UnownedStringSlice name;
        SourceLoc loc;

        StringSliceLoc()
            : name(nullptr)
        {}
        explicit StringSliceLoc(const UnownedStringSlice& inName)
            : name(inName)
        {}
        StringSliceLoc(const UnownedStringSlice& inName, SourceLoc inLoc)
            : name(inName)
            , loc(inLoc)
        {}
        StringSliceLoc(Token const& token)
            : loc(token.getLoc())
        {
            Name* tokenName = token.getNameOrNull();
            if (tokenName)
            {
                name = tokenName->text.getUnownedSlice();
            }
        }
    };

    // Helper class for iterating over a list of heap-allocated modifiers
    struct ModifierList
    {
        struct Iterator
        {
            Modifier* current = nullptr;

            Modifier* operator*()
            {
                return current;
            }

            void operator++();

            bool operator!=(Iterator other)
            {
                return current != other.current;
            };

            Iterator()
                : current(nullptr)
            {}

            Iterator(Modifier* modifier)
                : current(modifier)
            {}
        };

        ModifierList()
            : modifiers(nullptr)
        {}

        ModifierList(Modifier* modifiers)
            : modifiers(modifiers)
        {}

        Iterator begin() { return Iterator(modifiers); }
        Iterator end() { return Iterator(nullptr); }

        Modifier* modifiers = nullptr;
    };

    // Helper class for iterating over heap-allocated modifiers
    // of a specific type.
    template<typename T>
    struct FilteredModifierList
    {
        struct Iterator
        {
            Modifier* current = nullptr;

            T* operator*()
            {
                return (T*)current;
            }

            void operator++();

            bool operator!=(Iterator other)
            {
                return current != other.current;
            };

            Iterator()
                : current(nullptr)
            {}

            Iterator(Modifier* modifier)
                : current(modifier)
            {}
        };

        FilteredModifierList()
            : modifiers(nullptr)
        {}

        FilteredModifierList(Modifier* modifiers)
            : modifiers(adjust(modifiers))
        {}

        Iterator begin() { return Iterator(modifiers); }
        Iterator end() { return Iterator(nullptr); }

        static Modifier* adjust(Modifier* modifier);

        Modifier* modifiers = nullptr;
    };

    // A set of modifiers attached to a syntax node
    struct Modifiers
    {
        // The first modifier in the linked list of heap-allocated modifiers
        Modifier* first = nullptr;

        template<typename T>
        FilteredModifierList<T> getModifiersOfType() { return FilteredModifierList<T>(first); }

        // Find the first modifier of a given type, or return `nullptr` if none is found.
        template<typename T>
        T* findModifier()
        {
            return *getModifiersOfType<T>().begin();
        }

        template<typename T>
        bool hasModifier() { return findModifier<T>() != nullptr; }

            /// True if has no modifiers
        bool isEmpty() const { return first == nullptr; }

        FilteredModifierList<Modifier>::Iterator begin() { return FilteredModifierList<Modifier>::Iterator(first); }
        FilteredModifierList<Modifier>::Iterator end() { return FilteredModifierList<Modifier>::Iterator(nullptr); }
    };

    class NamedExpressionType;
    class GenericDecl;
    class ContainerDecl;

    // Try to extract a simple integer value from an `IntVal`.
    // This fill assert-fail if the object doesn't represent a literal value.
    IntegerLiteralValue getIntVal(IntVal* val);

        /// Represents how much checking has been applied to a declaration.
    enum class DeclCheckState : uint8_t
    {
            /// The declaration has been parsed, but
            /// is otherwise completely unchecked.
            ///
        Unchecked,

            /// Basic checks on the modifiers of the declaration have been applied.
            ///
            /// For example, when a declaration has attributes, the transformation
            /// of an attribute from the parsed-but-unchecked form into a checked
            /// form (in which it has the appropriate C++ subclass) happens here.
            ///
        ModifiersChecked,

            /// The type/signature of the declaration has been checked.
            ///
            /// For a value declaration like a variable or function, this means that
            /// the type of the declaration can be queried.
            ///
            /// For a type declaration like a `struct` or `typedef` this means
            /// that a `Type` referring to that declaration can be formed.
            ///
        SignatureChecked,

            /// The declaration's basic signature has been checked to the point that
            /// it is ready to be referenced in other places.
            ///
            /// For a function, this means that it has been organized into a
            /// "redeclration group" if there are multiple functions with the
            /// same name in a scope.
            ///
        ReadyForReference,

            /// The declaration is ready for lookup operations to be performed.
            ///
            /// For type declarations (e.g., aggregate types, generic type parameters)
            /// this means that any base type or constraint clauses have been
            /// sufficiently checked so that we can enumerate the inheritance
            /// hierarchy of the type and discover all its members.
            ///
        ReadyForLookup,

            /// Any conformance declared on the declaration have been validated.
            ///
            /// In particular, this step means that a "witness table" has been
            /// created to show  how a type satisfies the requirements of any
            /// interfaces it conforms to.
            ///
        ReadyForConformances,

            /// Any DeclRefTypes with substitutions have been fully resolved
            /// to concrete type. E.g. `T.X` with `T=A` should resolve to `A.X`.
            /// We need a separate pass to resolve these types because `A.X`
            /// maybe synthesized and made available only after conformance checking.
        TypesFullyResolved,

            /// The declaration is fully checked.
            ///
            /// This step includes any validation of the declaration that is
            /// immaterial to clients code using the declaration, but that is
            /// nonetheless relevant to checking correctness.
            ///
            /// The canonical example here is checking the body of functions.
            /// Client code cannot depend on *how* a function is implemented,
            /// but we still need to (eventually) check the bodies of all
            /// functions, so it belongs in the last phase of checking.
            ///
        Checked,

        // For convenience at sites that call `ensureDecl()`, we define
        // some aliases for the above states that are expressed in terms
        // of what client code needs to be able to do with a declaration.
        //
        // These aliases can be changed over time if we decide to add
        // more phases to semantic checking.

        CanEnumerateBases = ReadyForLookup,
        CanUseBaseOfInheritanceDecl = ReadyForLookup,
        CanUseTypeOfValueDecl = ReadyForReference,
        CanUseExtensionTargetType = ReadyForLookup,
        CanUseAsType = ReadyForReference,
        CanUseFuncSignature = ReadyForReference,
        CanSpecializeGeneric = ReadyForReference,
        CanReadInterfaceRequirements = ReadyForLookup,
    };

        /// A `DeclCheckState` plus a bit to track whether a declaration is currently being checked.
    struct DeclCheckStateExt
    {
        SLANG_VALUE_CLASS(DeclCheckStateExt)

        typedef uint8_t RawType;
        DeclCheckStateExt() {}
        DeclCheckStateExt(DeclCheckState state)
            : m_raw(uint8_t(state))
        {}

        enum : RawType
        {
                /// A flag to indicate that a declaration is being checked.
                ///
                /// The value of this flag is chosen so that it can be
                /// represented in the bits of a `DeclCheckState` without
                /// colliding with the bits that represent actual states.
                ///
            kBeingCheckedBit = 0x80,
        };

        DeclCheckState getState() const { return DeclCheckState(m_raw & ~kBeingCheckedBit); }
        void setState(DeclCheckState state)
        {
            m_raw = (m_raw & kBeingCheckedBit) | RawType(state);
        }

        bool isBeingChecked() const { return (m_raw & kBeingCheckedBit) != 0; }

        void setIsBeingChecked(bool isBeingChecked)
        {
            m_raw = (m_raw & ~kBeingCheckedBit)
                | (isBeingChecked ? kBeingCheckedBit : 0);
        }

        bool operator>=(DeclCheckState state) const
        {
            return getState() >= state;
        }

        RawType getRaw() const { return m_raw; }
        void setRaw(RawType raw) { m_raw = raw; }

        // TODO(JS):
        // Unfortunately for automatic serialization to see this member, it has to be public.
    //private:
        RawType m_raw = 0;
    };

    void addModifier(
        ModifiableSyntaxNode*    syntax,
        Modifier*                modifier);

    void removeModifier(
        ModifiableSyntaxNode* syntax,
        Modifier* modifier);

    struct QualType
    {
        SLANG_VALUE_CLASS(QualType)

        Type*	type = nullptr;
        bool	        isLeftValue;

        QualType()
            : isLeftValue(false)
        {}

        QualType(Type* type);

        Type* Ptr() { return type; }

        operator Type*() { return type; }
        Type* operator->() { return type; }
    };

    class ASTBuilder;

    struct ASTClassInfo
    {
        struct Infos
        {
            const ReflectClassInfo* infos[int(ASTNodeType::CountOf)];
        };
        SLANG_FORCE_INLINE static const ReflectClassInfo* getInfo(ASTNodeType type) { return kInfos.infos[int(type)]; }
        static const Infos kInfos;
    };

    // A reference to a class of syntax node, that can be
    // used to create instances on the fly
    struct SyntaxClassBase
    {
        SyntaxClassBase()
        {}

        SyntaxClassBase(ReflectClassInfo const* inClassInfo)
            : classInfo(inClassInfo)
        {}

        void* createInstanceImpl(ASTBuilder* astBuilder) const
        {
            auto ci = classInfo;
            if (!ci) return nullptr;

            auto cf = ci->m_createFunc;
            if (!cf) return nullptr;

            return cf(astBuilder);
        }

        SLANG_FORCE_INLINE bool isSubClassOfImpl(SyntaxClassBase const& super) const
        {
            return classInfo ? classInfo->isSubClassOf(*super.classInfo) : false;
        }

        ReflectClassInfo const* classInfo = nullptr;
    };

    template<typename T>
    struct SyntaxClass : SyntaxClassBase
    {
        SyntaxClass()
        {}

        template <typename U>
        SyntaxClass(SyntaxClass<U> const& other,
            typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
            : SyntaxClassBase(other.classInfo)
        {
        }

        T* createInstance(ASTBuilder* astBuilder) const
        {
            return (T*)createInstanceImpl(astBuilder);
        }

        SyntaxClass(const ReflectClassInfo* inClassInfo):
            SyntaxClassBase(inClassInfo)
        {}

        static SyntaxClass<T> getClass()
        {
            return SyntaxClass<T>(&T::kReflectClassInfo);
        }

        template<typename U>
        bool isSubClassOf(SyntaxClass<U> super)
        {
            return isSubClassOfImpl(super);
        }

        template<typename U>
        bool isSubClassOf()
        {
            return isSubClassOf(SyntaxClass<U>::getClass());
        }

        template<typename U>
        bool operator==(const SyntaxClass<U> other) const
        {
            return classInfo == other.classInfo;
        }

        template<typename U>
        bool operator!=(const SyntaxClass<U> other) const
        {
            return classInfo != other.classInfo;
        }
    };

    template<typename T>
    SyntaxClass<T> getClass()
    {
        return SyntaxClass<T>::getClass();
    }

    struct SubstitutionSet
    {
        Substitutions* substitutions = nullptr;
        operator Substitutions*() const
        {
            return substitutions;
        }

        SubstitutionSet() {}
        SubstitutionSet(Substitutions* subst)
            : substitutions(subst)
        {
        }
        bool equals(const SubstitutionSet& substSet) const;
        HashCode getHashCode() const;
    };

        /// An expression together with (optional) substutions to apply to it
        ///
        /// Under the hood this is a pair of an `Expr*` and a `SubstitutionSet`.
        /// Conceptually it represents the result of applying the substitutions,
        /// recursively, to the given expression.
        ///
        /// `SubstExprBase` exists primarily to provide a non-templated base type
        /// for `SubstExpr<T>`. Code should prefer to use `SubstExpr<Expr>` instead
        /// of `SubstExprBase` as often as possible.
        ///
    struct SubstExprBase
    {
    public:
            /// Initialize as a null expression
        SubstExprBase()
        {}

            /// Initialize as the given `expr` with no subsitutions applied
        SubstExprBase(Expr* expr)
            : m_expr(expr)
        {}

            /// Initialize as the given `expr` with the given `substs` applied
        SubstExprBase(Expr* expr, SubstitutionSet const& substs)
            : m_expr(expr)
            , m_substs(substs)
        {}

            /// Get the underlying expression without any substitutions
        Expr* getExpr() const { return m_expr; }

            /// Get the subsitutions being applied, if any
        SubstitutionSet const& getSubsts() const { return m_substs; }

    private:
        Expr*           m_expr = nullptr;
        SubstitutionSet m_substs;

        typedef void (SubstExprBase::*SafeBool)();
        void SafeBoolTrue() {}

    public:
            /// Test whether this is a non-null expression
        operator SafeBool()
        {
            return m_expr ? &SubstExprBase::SafeBoolTrue : nullptr;
        }

            /// Test whether this is a null expression
        bool operator!() const { return m_expr == nullptr; }

    };

        /// An expression together with (optional) substutions to apply to it
        ///
        /// Under the hood this is a pair of an `T*` (there `T: Expr`) and a `SubstitutionSet`.
        /// Conceptually it represents the result of applying the substitutions,
        /// recursively, to the given expression.
        ///
    template<typename T>
    struct SubstExpr : SubstExprBase
    {
    private:
        typedef SubstExprBase Super;

    public:
            /// Initialize as a null expression
        SubstExpr()
        {}

            /// Initialize as the given `expr` with no subsitutions applied
        SubstExpr(T* expr)
            : Super(expr)
        {}

            /// Initialize as the given `expr` with the given `substs` applied
        SubstExpr(T* expr, SubstitutionSet const& substs)
            : Super(expr, substs)
        {}

            /// Initialize as a copy of the given `other` expression
        template <typename U>
        SubstExpr(SubstExpr<U> const& other,
            typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
            : Super(other.getExpr(), other.getSubsts())
        {
        }

            /// Get the underlying expression without any substitutions
        T* getExpr() const { return (T*) Super::getExpr(); }

            /// Dynamic cast to an expression of type `U`
            ///
            /// Returns a null expression if the cast fails, or if this expression was null.
        template<typename U>
        SubstExpr<U> as()
        {
            return SubstExpr<U>(Slang::as<U>(getExpr()), getSubsts());
        }
    };

    class ASTBuilder;

    template<typename T>
    struct DeclRef;

    // A reference to a declaration, which may include
    // substitutions for generic parameters.
    struct DeclRefBase
    {
        typedef Decl DeclType;

        // The underlying declaration
        Decl* decl = nullptr;
        Decl* getDecl() const { return decl; }

        // Optionally, a chain of substitutions to perform
        SubstitutionSet substitutions;

        DeclRefBase()
        {}

        DeclRefBase(Decl* decl)
            :decl(decl)
        {}

        DeclRefBase(Decl* decl, SubstitutionSet subst)
            :decl(decl),
            substitutions(subst)
        {}

        DeclRefBase(Decl* decl, Substitutions* subst)
            : decl(decl)
            , substitutions(subst)
        {}

        // Apply substitutions to a type or declaration
        Type* substitute(ASTBuilder* astBuilder, Type* type) const;

        DeclRefBase substitute(ASTBuilder* astBuilder, DeclRefBase declRef) const;

        // Apply substitutions to an expression
        SubstExpr<Expr> substitute(ASTBuilder* astBuilder, Expr* expr) const;

        // Apply substitutions to this declaration reference
        DeclRefBase substituteImpl(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff) const;

        // Returns true if 'as' will return a valid cast
        template <typename T>
        bool is() const { return Slang::as<T>(decl) != nullptr; }

        // "dynamic cast" to a more specific declaration reference type
        template<typename T>
        DeclRef<T> as() const;

        // Check if this is an equivalent declaration reference to another
        bool equals(DeclRefBase const& declRef) const;
        bool operator == (const DeclRefBase& other) const
        {
            return equals(other);
        }

        // Convenience accessors for common properties of declarations
        Name* getName() const;
        SourceLoc getNameLoc() const;
        SourceLoc getLoc() const;
        DeclRefBase getParent() const;

        HashCode getHashCode() const;

        // Debugging:
        String toString() const;
        void toText(StringBuilder& out) const;
    };

    // If this is a declref to an associatedtype with a ThisTypeSubsitution,
    // try to find the concrete decl that satisfies the associatedtype requirement from the
    // concrete type supplied by ThisTypeSubstittution.
    Val* _tryLookupConcreteAssociatedTypeFromThisTypeSubst(ASTBuilder* builder, DeclRef<Decl> declRef);
    void _printNestedDecl(const Substitutions* substitutions, Decl* decl, StringBuilder& out);

    template<typename T>
    struct DeclRef : DeclRefBase
    {
        typedef T DeclType;

        DeclRef()
        {}

        DeclRef(T* decl, SubstitutionSet subst)
            : DeclRefBase(decl, subst)
        {}

        DeclRef(T* decl, Substitutions* subst)
            : DeclRefBase(decl, SubstitutionSet(subst))
        {}

        template <typename U>
        DeclRef(DeclRef<U> const& other,
            typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
            : DeclRefBase(other.decl, other.substitutions)
        {
        }

        T* getDecl() const
        {
            return (T*)decl;
        }

        operator T*() const
        {
            return getDecl();
        }

        //
        static DeclRef<T> unsafeInit(DeclRefBase const& declRef)
        {
            return DeclRef<T>((T*) declRef.decl, declRef.substitutions);
        }

        Type* substitute(ASTBuilder* astBuilder, Type* type) const
        {
            return DeclRefBase::substitute(astBuilder, type);
        }

        SubstExpr<Expr> substitute(ASTBuilder* astBuilder, Expr* expr) const
        {
            return DeclRefBase::substitute(astBuilder, expr);
        }

        // Apply substitutions to a type or declaration
        template<typename U>
        DeclRef<U> substitute(ASTBuilder* astBuilder, DeclRef<U> declRef) const
        {
            return DeclRef<U>::unsafeInit(DeclRefBase::substitute(astBuilder, declRef));
        }

        // Apply substitutions to this declaration reference
        DeclRef<T> substituteImpl(ASTBuilder* astBuilder, SubstitutionSet subst, int* ioDiff) const
        {
            return DeclRef<T>::unsafeInit(DeclRefBase::substituteImpl(astBuilder, subst, ioDiff));
        }

        DeclRef<ContainerDecl> getParent() const
        {
            return DeclRef<ContainerDecl>::unsafeInit(DeclRefBase::getParent());
        }
    };

    SubstExpr<Expr> substituteExpr(SubstitutionSet const& substs, Expr* expr);
    DeclRef<Decl> substituteDeclRef(SubstitutionSet const& substs, ASTBuilder* astBuilder, DeclRef<Decl> const& declRef);
    Type* substituteType(SubstitutionSet const& substs, ASTBuilder* astBuilder, Type* type);

    SLANG_FORCE_INLINE StringBuilder& operator<<(StringBuilder& io, const DeclRefBase& declRef) { declRef.toText(io); return io; }

    template<typename T>
    DeclRef<T> DeclRefBase::as() const
    {
        DeclRef<T> result;
        result.decl = Slang::as<T>(decl);
        result.substitutions = substitutions;
        return result;
    }

    template<typename T>
    inline DeclRef<T> makeDeclRef(T* decl)
    {
        return DeclRef<T>(decl, nullptr);
    }

    enum class MemberFilterStyle
    {
        All,                        ///< All members
        Instance,                   ///< Only instance members
        Static,                     ///< Only static (ie non instance) members
    };

    Decl*const* adjustFilterCursorImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end);
    Decl*const* getFilterCursorByIndexImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end, Index index);
    Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end);

    template <typename T>
    Decl*const* adjustFilterCursor(MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end)
    {
        return adjustFilterCursorImpl(T::kReflectClassInfo, filterStyle, ptr, end);
    }

        /// Finds the element at index. If there is no element at the index (for example has too few elements), returns nullptr.
    template <typename T>
    Decl*const* getFilterCursorByIndex(MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end, Index index)
    {
        return getFilterCursorByIndexImpl(T::kReflectClassInfo, filterStyle, ptr, end, index);
    }

    template <typename T>
    Index getFilterCount(MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end)
    {
        return getFilterCountImpl(T::kReflectClassInfo, filterStyle, ptr, end);
    }

    template <typename T>
    bool isFilterNonEmpty(MemberFilterStyle filterStyle, Decl*const* ptr, Decl*const* end)
    {
        return adjustFilterCursorImpl(T::kReflectClassInfo, filterStyle, ptr, end) != end;
    }

    template<typename T>
    struct FilteredMemberList
    {
        typedef Decl* Element;

        FilteredMemberList()
            : m_begin(nullptr)
            , m_end(nullptr)
        {}

        explicit FilteredMemberList(
            List<Element> const& list,
            MemberFilterStyle filterStyle = MemberFilterStyle::All)
            : m_begin(adjustFilterCursor<T>(filterStyle, list.begin(), list.end()))
            , m_end(list.end())
            , m_filterStyle(filterStyle)
        {}

        struct Iterator
        {
            const Element* m_cursor;
            const Element* m_end;
            MemberFilterStyle m_filterStyle;

            bool operator!=(Iterator const& other) const { return m_cursor != other.m_cursor; }

            void operator++() { m_cursor = adjustFilterCursor<T>(m_filterStyle, m_cursor + 1, m_end); }

            T* operator*() { return  static_cast<T*>(*m_cursor); }
        };

        Iterator begin()
        {
            Iterator iter = { m_begin, m_end, m_filterStyle };
            return iter;
        }

        Iterator end()
        {
            Iterator iter = { m_end, m_end, m_filterStyle };
            return iter;
        }

        // TODO(tfoley): It is ugly to have these.
        // We should probably fix the call sites instead.
        T* getFirst() { return *begin(); }
        Index getCount() { return getFilterCount<T>(m_filterStyle, m_begin, m_end); }

        T* operator[](Index index) const
        {
            Decl*const* ptr = getFilterCursorByIndex<T>(m_filterStyle, m_begin, m_end, index);
            SLANG_ASSERT(ptr);
            return  static_cast<T*>(*ptr);
        }

            /// Returns true if empty (equivalent to getCount() == 0)
        bool isEmpty() const
        {
            /// Note we don't have to scan, because m_begin has already been adjusted, when the FilteredMemberList is constructed
            return m_begin == m_end;
        }
            /// Returns true if non empty (equivalent to getCount() != 0 but faster)
        bool isNonEmpty() const { return !isEmpty(); }

        List<T*> toList()
        {
            List<T*> result;
            for (auto element : (*this))
            {
                result.add(element);
            }
            return result;
        }

        const Element* m_begin;             ///< Is either equal to m_end, or points to first *valid* filtered member
        const Element* m_end;
        MemberFilterStyle m_filterStyle;
    };

    struct TransparentMemberInfo
    {
        // The declaration of the transparent member
        Decl*	decl = nullptr;
    };

    template<typename T>
    struct FilteredMemberRefList
    {
        List<Decl*> const&	m_decls;
        SubstitutionSet		m_substitutions;
        MemberFilterStyle   m_filterStyle;

        FilteredMemberRefList(
            List<Decl*> const&	decls,
            SubstitutionSet		substitutions,
            MemberFilterStyle   filterStyle = MemberFilterStyle::All)
            : m_decls(decls)
            , m_substitutions(substitutions)
            , m_filterStyle(filterStyle)
        {}

        Index getCount() const { return getFilterCount<T>(m_filterStyle, m_decls.begin(), m_decls.end()); }

            /// True if empty (equivalent to getCount == 0, but faster)
        bool isEmpty() const { return !isNonEmpty(); }
            /// True if non empty (equivalent to getCount() != 0 but faster)
        bool isNonEmpty() const { return isFilterNonEmpty<T>(m_filterStyle, m_decls.begin(), m_decls.end()); }

        DeclRef<T> getFirstOrNull() { return isEmpty() ? DeclRef<T>() : (*this)[0]; }

        DeclRef<T> operator[](Index index) const
        {
             Decl*const* decl = getFilterCursorByIndex<T>(m_filterStyle, m_decls.begin(), m_decls.end(), index);
             SLANG_ASSERT(decl);
             return DeclRef<T>((T*) *decl, m_substitutions);
        }

        List<DeclRef<T>> toArray() const
        {
            List<DeclRef<T>> result;
            for (auto d : *this)
                result.add(d);
            return result;
        }

        struct Iterator
        {
            FilteredMemberRefList const* m_list;
            Decl*const* m_ptr;
            Decl*const* m_end;
            MemberFilterStyle m_filterStyle;

            Iterator() : m_list(nullptr), m_ptr(nullptr), m_filterStyle(MemberFilterStyle::All) {}
            Iterator(
                FilteredMemberRefList const* list,
                Decl*const* ptr,
                Decl*const* end,
                MemberFilterStyle filterStyle
                )
                : m_list(list)
                , m_ptr(ptr)
                , m_end(end)
                , m_filterStyle(filterStyle)
            {}

            bool operator!=(const Iterator& other) const  { return m_ptr != other.m_ptr; }

            void operator++() { m_ptr = adjustFilterCursor<T>(m_filterStyle, m_ptr + 1, m_end); }

            DeclRef<T> operator*() { return DeclRef<T>((T*)*m_ptr, m_list->m_substitutions); }
        };

        Iterator begin() const { return Iterator(this, adjustFilterCursor<T>(m_filterStyle, m_decls.begin(), m_decls.end()), m_decls.end(), m_filterStyle); }
        Iterator end() const { return Iterator(this, m_decls.end(), m_decls.end(), m_filterStyle); }
    };

    //
    // type Expressions
    //

    // A "type expression" is a term that we expect to resolve to a type during checking.
    // We store both the original syntax and the resolved type here.
    struct TypeExp
    {
        SLANG_VALUE_CLASS(TypeExp)
        typedef TypeExp ThisType;

        TypeExp() {}
        TypeExp(TypeExp const& other)
            : exp(other.exp)
            , type(other.type)
        {}
        explicit TypeExp(Expr* exp)
            : exp(exp)
        {}
        explicit TypeExp(Type* type)
            : type(type)
        {}
        TypeExp(Expr* exp, Type* type)
            : exp(exp)
            , type(type)
        {}

        Expr* exp = nullptr;
        Type* type = nullptr;

        bool equals(Type* other);

        Type* Ptr() { return type; }
        operator Type*()
        {
            return type;
        }
        Type* operator->() { return Ptr(); }

        ThisType& operator=(const ThisType& rhs) = default;

        //TypeExp accept(SyntaxVisitor* visitor);

            /// A global immutable TypeExp, that has no type or exp set.
        static const TypeExp empty;
    };

    // Masks to be applied when lookup up declarations
    enum class LookupMask : uint8_t
    {
        type = 0x1,
        Function = 0x2,
        Value = 0x4,
        Attribute = 0x8,
        Default = type | Function | Value,
    };

        /// Flags for options to be used when looking up declarations
    enum class LookupOptions : uint8_t
    {
        None = 0,
        IgnoreBaseInterfaces = 1 << 0,
        Completion = 1 << 1, ///< Lookup all applicable decls for code completion suggestions
        NoDeref = 1 << 2,
    };

    class SerialRefObject;

    // Make sure C++ extractor can see the base class.
    SLANG_PRE_DECLARE(OBJ, class SerialRefObject)

    SLANG_TYPE_SET(OBJ, RefObject)
    SLANG_TYPE_SET(VALUE, Value)
    SLANG_TYPE_SET(AST, ASTNode)

    class LookupResultItem_Breadcrumb : public SerialRefObject
    {
    public:
        SLANG_OBJ_CLASS(LookupResultItem_Breadcrumb)

        enum class Kind : uint8_t
        {
            // The lookup process looked "through" an in-scope
            // declaration to the fields inside of it, so that
            // even if lookup started with a simple name `f`,
            // it needs to result in a member expression `obj.f`.
            Member,

            // The lookup process took a pointer(-like) value, and then
            // proceeded to derefence it and look at the thing(s)
            // it points to instead, so that the final expression
            // needs to have `(*obj)`
            Deref,

            // The lookup process saw a value `obj` of type `T` and
            // took into account an in-scope constraint that says
            // `T` is a subtype of some other type `U`, so that
            // lookup was able to find a member through type `U`
            // instead.
            SuperType,

            // The lookup process considered a member of an
            // enclosing type as being in scope, so that any
            // reference to that member needs to use a `this`
            // expression as appropriate.
            This,
        };

        // The kind of lookup step that was performed
        Kind kind;

        // For the `Kind::This` case, what does the implicit
        // `this` or `This` parameter refer to?
        //
        enum class ThisParameterMode : uint8_t
        {
            ImmutableValue, // An immutable `this` value
            MutableValue,   // A mutable `this` value
            Type,           // A `This` type

            Default = ImmutableValue,
        };
        ThisParameterMode thisParameterMode = ThisParameterMode::Default;

        // As needed, a reference to the declaration that faciliated
        // the lookup step.
        //
        // For a `Member` lookup step, this is the declaration whose
        // members were implicitly pulled into scope.
        //
        // For a `Constraint` lookup step, this is the `ConstraintDecl`
        // that serves to witness the subtype relationship.
        //
        DeclRef<Decl> declRef;

        Val* val = nullptr;

        // The next implicit step that the lookup process took to
        // arrive at a final value.
        RefPtr<LookupResultItem_Breadcrumb> next;

        LookupResultItem_Breadcrumb(
            Kind                kind,
            DeclRef<Decl>       declRef,
            Val*                val,
            RefPtr<LookupResultItem_Breadcrumb>  next,
            ThisParameterMode   thisParameterMode = ThisParameterMode::Default)
            : kind(kind)
            , thisParameterMode(thisParameterMode)
            , declRef(declRef)
            , val(val)
            , next(next)
        {}
    protected:
        // Needed for serialization
        LookupResultItem_Breadcrumb() = default;
    };

    // Represents one item found during lookup
    struct LookupResultItem
    {
        SLANG_VALUE_CLASS(LookupResultItem)

        typedef LookupResultItem_Breadcrumb Breadcrumb;

        // Sometimes lookup finds an item, but there were additional
        // "hops" taken to reach it. We need to remember these steps
        // so that if/when we consturct a full expression we generate
        // appropriate AST nodes for all the steps.
        //
        // We build up a list of these "breadcrumbs" while doing
        // lookup, and store them alongside each item found.
        //
        // As an example, suppose we have an HLSL `cbuffer` declaration:
        //
        //     cbuffer C { float4 f; }
        //
        // This is syntax sugar for a global-scope variable of
        // type `ConstantBuffer<T>` where `T` is a `struct` containing
        // all the members:
        //
        //     struct Anon0 { float4 f; };
        //     __transparent ConstantBuffer<Anon0> anon1;
        //
        // The `__transparent` modifier there captures the fact that
        // when somebody writes `f` in their code, they expect it to
        // "see through" the `cbuffer` declaration (or the global variable,
        // in this case) and find the member inside.
        //
        // But when the user writes `f` we can't just create a simple
        // `VarExpr` that refers directly to that field, because that
        // doesn't actually reflect the required steps in a way that
        // code generation can use.
        //
        // Instead we need to construct an expression like `(*anon1).f`,
        // where there is are two additional steps in the process:
        //
        // 1. We needed to dereference the pointer-like type `ConstantBuffer<Anon0>`
        //    to get at a value of type `Anon0`
        // 2. We needed to access a sub-field of the aggregate type `Anon0`
        //
        // We *could* just create these full-formed expressions during
        // lookup, but this might mean creating a large number of
        // AST nodes in cases where the user calls an overloaded function.
        // At the very least we'd rather not heap-allocate in the common
        // case where no "extra" steps need to be performed to get to
        // the declarations.
        //
        // This is where "breadcrumbs" come in. A breadcrumb represents
        // an extra "step" that must be performed to turn a declaration
        // found by lookup into a valid expression to splice into the
        // AST. Most of the time lookup result items don't have any
        // breadcrumbs, so that no extra heap allocation takes place.
        // When an item does have breadcrumbs, and it is chosen as
        // the unique result (perhaps by overload resolution), then
        // we can walk the list of breadcrumbs to create a full
        // expression.

        // A properly-specialized reference to the declaration that was found.
        DeclRef<Decl> declRef;

        // Any breadcrumbs needed in order to turn that declaration
        // reference into a well-formed expression.
        //
        // This is unused in the simple case where a declaration
        // is being referenced directly (rather than through
        // transparent members).
        RefPtr<LookupResultItem_Breadcrumb> breadcrumbs;

        LookupResultItem() = default;
        explicit LookupResultItem(DeclRef<Decl> declRef)
            : declRef(declRef)
        {}
        LookupResultItem(DeclRef<Decl> declRef, RefPtr<Breadcrumb> breadcrumbs)
            : declRef(declRef)
            , breadcrumbs(breadcrumbs)
        {}
    };

    // Result of looking up a name in some lexical/semantic environment.
    // Can be used to enumerate all the declarations matching that name,
    // in the case where the result is overloaded.
    struct LookupResult
    {
        // The one item that was found, in the simple case
        LookupResultItem item;

        // All of the items that were found, in the complex case.
        // Note: if there was no overloading, then this list isn't
        // used at all, to avoid allocation.
        //
        // Additionally, if `items` is used, then `item` *must* hold an item that
        // is also in the items list (typically the first entry), as an invariant.
        // Otherwise isValid/begin will not function correctly.
        List<LookupResultItem> items;

        // Was at least one result found?
        bool isValid() const { return item.declRef.getDecl() != nullptr; }

        bool isOverloaded() const { return items.getCount() > 1; }

        Name* getName() const
        {
            return items.getCount() > 1 ? items[0].declRef.getName() : item.declRef.getName();
        }
        LookupResultItem* begin() const
        {
            if (isValid())
            {
                if (isOverloaded())
                    return const_cast<LookupResultItem*>(items.begin());
                else
                    return const_cast<LookupResultItem*>(&item);
            }
            else
                return nullptr;
        }
        LookupResultItem* end() const
        {
            if (isValid())
            {
                if (isOverloaded())
                    return const_cast<LookupResultItem*>(items.end());
                else
                    return const_cast<LookupResultItem*>(&item + 1);
            }
            else
                return nullptr;
        }
    };

    struct SemanticsVisitor;

    struct LookupRequest
    {
        SemanticsVisitor*   semantics   = nullptr;
        Scope*              scope       = nullptr;
        Scope*              endScope    = nullptr;

        LookupMask          mask        = LookupMask::Default;
        LookupOptions       options     = LookupOptions::None;

        bool isCompletionRequest() const { return ((int)options & (int)LookupOptions::Completion) != 0; }
    };

    struct WitnessTable;

    // A value that witnesses the satisfaction of an interface
    // requirement by a particular declaration or value.
    struct RequirementWitness
    {
        SLANG_VALUE_CLASS(RequirementWitness)

        RequirementWitness()
            : m_flavor(Flavor::none)
        {}

        RequirementWitness(DeclRef<Decl> declRef)
            : m_flavor(Flavor::declRef)
            , m_declRef(declRef)
        {}

        RequirementWitness(Val* val);

        RequirementWitness(RefPtr<WitnessTable> witnessTable);

        enum class Flavor
        {
            none,
            declRef,
            val,
            witnessTable,
        };

        Flavor getFlavor()
        {
            return m_flavor;
        }

        DeclRef<Decl> getDeclRef()
        {
            SLANG_ASSERT(getFlavor() == Flavor::declRef);
            return m_declRef;
        }

        Val* getVal()
        {
            SLANG_ASSERT(getFlavor() == Flavor::val);
            return m_val;
        }

        RefPtr<WitnessTable> getWitnessTable();

        RequirementWitness specialize(ASTBuilder* astBuilder, SubstitutionSet const& subst);

        Flavor              m_flavor;
        DeclRef<Decl>       m_declRef;
        RefPtr<RefObject>   m_obj;
        Val*                m_val = nullptr;
    };

    typedef OrderedDictionary<Decl*, RequirementWitness> RequirementDictionary;

    struct WitnessTable : SerialRefObject
    {
        SLANG_OBJ_CLASS(WitnessTable)

        RequirementDictionary requirementDictionary;

        void add(Decl* decl, RequirementWitness const& witness);

        // The type that the witness table witnesses conformance to (e.g. an Interface)
        Type* baseType;

        // The type witnessesd by the witness table (a concrete type).
        Type* witnessedType;
    };

    typedef Dictionary<unsigned int, NodeBase*> AttributeArgumentValueDict;

    struct SpecializationParam
    {
        enum class Flavor
        {
            GenericType,
            GenericValue,
            ExistentialType,
            ExistentialValue,
        };
        Flavor              flavor;
        SourceLoc           loc;
        NodeBase*    object = nullptr;
    };
    typedef List<SpecializationParam> SpecializationParams;

    struct SpecializationArg
    {
        SLANG_VALUE_CLASS(SpecializationArg)
        Val* val = nullptr;
    };
    typedef List<SpecializationArg> SpecializationArgs;

    struct ExpandedSpecializationArg : SpecializationArg
    {
        SLANG_VALUE_CLASS(ExpandedSpecializationArg)
        Val* witness = nullptr;
    };
    typedef List<ExpandedSpecializationArg> ExpandedSpecializationArgs;

        /// A reference-counted object to hold a list of candidate extensions
        /// that might be applicable to a type based on its declaration.
        ///
    struct CandidateExtensionList : RefObject
    {
        List<ExtensionDecl*> candidateExtensions;
    };

    enum class DeclAssociationKind
    {
        ForwardDerivativeFunc, BackwardDerivativeFunc,
    };

    struct DeclAssociation
    {
        SLANG_VALUE_CLASS(DeclAssociation)
        DeclAssociationKind kind;
        Decl* decl;
    };

    /// A reference-counted object to hold a list of associated decls for a decl.
    ///
    struct DeclAssociationList : SerialRefObject
    {
        SLANG_OBJ_CLASS(DeclAssociationList)

        List<DeclAssociation> associations;
    };

        /// Represents the "direction" that a parameter is being passed (e.g., `in` or `out`
    enum ParameterDirection
    {
        kParameterDirection_In,     ///< Copy in
        kParameterDirection_Out,    ///< Copy out
        kParameterDirection_InOut,  ///< Copy in, copy out
        kParameterDirection_Ref,    ///< By-reference
    };

    /// The kind of a builtin interface requirement that can be automatically synthesized.
    enum class BuiltinRequirementKind
    {
        DifferentialType, ///< The `IDifferentiable.Differential` associated type requirement
        DZeroFunc, ///< The `IDifferentiable.dzero` function requirement
        DAddFunc, ///< The `IDifferentiable.dadd` function requirement
        DMulFunc, ///< The `IDifferentiable.dmul` function requirement
    };

    /// Get the inner most expr from an higher order expr chain, e.g. `__fwd_diff(__fwd_diff(f))`'s
    /// inner most expr is `f`.
    Expr* getInnerMostExprFromHigherOrderExpr(Expr* expr);

    /// Get the operator name from the higher order invoke expr.
    UnownedStringSlice getHigherOrderOperatorName(HigherOrderInvokeExpr* expr);

} // namespace Slang

#endif


text:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package scanner implements a scanner for Go source text.
// It takes a []byte as source which can then be tokenized
// through repeated calls to the Scan method.
//
package scanner

import (
	"bytes"
	"fmt"
	"go/token"
	"path/filepath"
	"strconv"
	"unicode"
	"unicode/utf8"
)

// An ErrorHandler may be provided to Scanner.Init. If a syntax error is
// encountered and a handler was installed, the handler is called with a
// position and an error message. The position points to the beginning of
// the offending token.
//
type ErrorHandler func(pos token.Position, msg string)

// A Scanner holds the scanner's internal state while processing
// a given text.  It can be allocated as part of another data
// structure but must be initialized via Init before use.
//
type Scanner struct {
	// immutable state
	file *token.File  // source file handle
	dir  string       // directory portion of file.Name()
	src  []byte       // source
	err  ErrorHandler // error reporting; or nil
	mode Mode         // scanning mode

	// scanning state
	ch         rune // current character
	offset     int  // character offset
	rdOffset   int  // reading offset (position after current character)
	lineOffset int  // current line offset
	insertSemi bool // insert a semicolon before next newline

	// public state - ok to modify
	ErrorCount int // number of errors encountered
}

const bom = 0xFEFF // byte order mark, only permitted as very first character

// Read the next Unicode char into s.ch.
// s.ch < 0 means end-of-file.
//
func (s *Scanner) next() {
	if s.rdOffset < len(s.src) {
		s.offset = s.rdOffset
		if s.ch == '\n' {
			s.lineOffset = s.offset
			s.file.AddLine(s.offset)
		}
		r, w := rune(s.src[s.rdOffset]), 1
		switch {
		case r == 0:
			s.error(s.offset, "illegal character NUL")
		case r >= 0x80:
			// not ASCII
			r, w = utf8.DecodeRune(s.src[s.rdOffset:])
			if r == utf8.RuneError && w == 1 {
				s.error(s.offset, "illegal UTF-8 encoding")
			} else if r == bom && s.offset > 0 {
				s.error(s.offset, "illegal byte order mark")
			}
		}
		s.rdOffset += w
		s.ch = r
	} else {
		s.offset = len(s.src)
		if s.ch == '\n' {
			s.lineOffset = s.offset
			s.file.AddLine(s.offset)
		}
		s.ch = -1 // eof
	}
}

// A mode value is a set of flags (or 0).
// They control scanner behavior.
//
type Mode uint

const (
	ScanComments    Mode = 1 << iota // return comments as COMMENT tokens
	dontInsertSemis                  // do not automatically insert semicolons - for testing only
)

// Init prepares the scanner s to tokenize the text src by setting the
// scanner at the beginning of src. The scanner uses the file set file
// for position information and it adds line information for each line.
// It is ok to re-use the same file when re-scanning the same file as
// line information which is already present is ignored. Init causes a
// panic if the file size does not match the src size.
//
// Calls to Scan will invoke the error handler err if they encounter a
// syntax error and err is not nil. Also, for each error encountered,
// the Scanner field ErrorCount is incremented by one. The mode parameter
// determines how comments are handled.
//
// Note that Init may call err if there is an error in the first character
// of the file.
//
func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
	// Explicitly initialize all fields since a scanner may be reused.
	if file.Size() != len(src) {
		panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size(), len(src)))
	}
	s.file = file
	s.dir, _ = filepath.Split(file.Name())
	s.src = src
	s.err = err
	s.mode = mode

	s.ch = ' '
	s.offset = 0
	s.rdOffset = 0
	s.lineOffset = 0
	s.insertSemi = false
	s.ErrorCount = 0

	s.next()
	if s.ch == bom {
		s.next() // ignore BOM at file beginning
	}
}

func (s *Scanner) error(offs int, msg string) {
	if s.err != nil {
		s.err(s.file.Position(s.file.Pos(offs)), msg)
	}
	s.ErrorCount++
}

var prefix = []byte("//line ")

func (s *Scanner) interpretLineComment(text []byte) {
	if bytes.HasPrefix(text, prefix) {
		// get filename and line number, if any
		if i := bytes.LastIndex(text, []byte{':'}); i > 0 {
			if line, err := strconv.Atoi(string(text[i+1:])); err == nil && line > 0 {
				// valid //line filename:line comment;
				filename := filepath.Clean(string(text[len(prefix):i]))
				if !filepath.IsAbs(filename) {
					// make filename relative to current directory
					filename = filepath.Join(s.dir, filename)
				}
				// update scanner position
				s.file.AddLineInfo(s.lineOffset+len(text)+1, filename, line) // +len(text)+1 since comment applies to next line
			}
		}
	}
}

func (s *Scanner) scanComment() string {
	// initial '/' already consumed; s.ch == '/' || s.ch == '*'
	offs := s.offset - 1 // position of initial '/'
	hasCR := false

	if s.ch == '/' {
		//-style comment
		s.next()
		for s.ch != '\n' && s.ch >= 0 {
			if s.ch == '\r' {
				hasCR = true
			}
			s.next()
		}
		if offs == s.lineOffset {
			// comment starts at the beginning of the current line
			s.interpretLineComment(s.src[offs:s.offset])
		}
		goto exit
	}

	/*-style comment */
	s.next()
	for s.ch >= 0 {
		ch := s.ch
		if ch == '\r' {
			hasCR = true
		}
		s.next()
		if ch == '*' && s.ch == '/' {
			s.next()
			goto exit
		}
	}

	s.error(offs, "comment not terminated")

exit:
	lit := s.src[offs:s.offset]
	if hasCR {
		lit = stripCR(lit)
	}

	return string(lit)
}

func (s *Scanner) findLineEnd() bool {
	// initial '/' already consumed

	defer func(offs int) {
		// reset scanner state to where it was upon calling findLineEnd
		s.ch = '/'
		s.offset = offs
		s.rdOffset = offs + 1
		s.next() // consume initial '/' again
	}(s.offset - 1)

	// read ahead until a newline, EOF, or non-comment token is found
	for s.ch == '/' || s.ch == '*' {
		if s.ch == '/' {
			//-style comment always contains a newline
			return true
		}
		/*-style comment: look for newline */
		s.next()
		for s.ch >= 0 {
			ch := s.ch
			if ch == '\n' {
				return true
			}
			s.next()
			if ch == '*' && s.ch == '/' {
				s.next()
				break
			}
		}
		s.skipWhitespace() // s.insertSemi is set
		if s.ch < 0 || s.ch == '\n' {
			return true
		}
		if s.ch != '/' {
			// non-comment token
			return false
		}
		s.next() // consume '/'
	}

	return false
}

func isLetter(ch rune) bool {
	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch)
}

func isDigit(ch rune) bool {
	return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
}

func (s *Scanner) scanIdentifier() string {
	offs := s.offset
	for isLetter(s.ch) || isDigit(s.ch) {
		s.next()
	}
	return string(s.src[offs:s.offset])
}

func digitVal(ch rune) int {
	switch {
	case '0' <= ch && ch <= '9':
		return int(ch - '0')
	case 'a' <= ch && ch <= 'f':
		return int(ch - 'a' + 10)
	case 'A' <= ch && ch <= 'F':
		return int(ch - 'A' + 10)
	}
	return 16 // larger than any legal digit val
}

func (s *Scanner) scanMantissa(base int) {
	for digitVal(s.ch) < base {
		s.next()
	}
}

func (s *Scanner) scanNumber(seenDecimalPoint bool) (token.Token, string) {
	// digitVal(s.ch) < 10
	offs := s.offset
	tok := token.INT

	if seenDecimalPoint {
		offs--
		tok = token.FLOAT
		s.scanMantissa(10)
		goto exponent
	}

	if s.ch == '0' {
		// int or float
		offs := s.offset
		s.next()
		if s.ch == 'x' || s.ch == 'X' {
			// hexadecimal int
			s.next()
			s.scanMantissa(16)
			if s.offset-offs <= 2 {
				// only scanned "0x" or "0X"
				s.error(offs, "illegal hexadecimal number")
			}
		} else {
			// octal int or float
			seenDecimalDigit := false
			s.scanMantissa(8)
			if s.ch == '8' || s.ch == '9' {
				// illegal octal int or float
				seenDecimalDigit = true
				s.scanMantissa(10)
			}
			if s.ch == '.' || s.ch == 'e' || s.ch == 'E' || s.ch == 'i' {
				goto fraction
			}
			// octal int
			if seenDecimalDigit {
				s.error(offs, "illegal octal number")
			}
		}
		goto exit
	}

	// decimal int or float
	s.scanMantissa(10)

fraction:
	if s.ch == '.' {
		tok = token.FLOAT
		s.next()
		s.scanMantissa(10)
	}

exponent:
	if s.ch == 'e' || s.ch == 'E' {
		tok = token.FLOAT
		s.next()
		if s.ch == '-' || s.ch == '+' {
			s.next()
		}
		s.scanMantissa(10)
	}

	if s.ch == 'i' {
		tok = token.IMAG
		s.next()
	}

exit:
	return tok, string(s.src[offs:s.offset])
}

func (s *Scanner) scanEscape(quote rune) {
	offs := s.offset

	var i, base, max uint32
	switch s.ch {
	case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
		s.next()
		return
	case '0', '1', '2', '3', '4', '5', '6', '7':
		i, base, max = 3, 8, 255
	case 'x':
		s.next()
		i, base, max = 2, 16, 255
	case 'u':
		s.next()
		i, base, max = 4, 16, unicode.MaxRune
	case 'U':
		s.next()
		i, base, max = 8, 16, unicode.MaxRune
	default:
		s.next() // always make progress
		s.error(offs, "unknown escape sequence")
		return
	}

	var x uint32
	for ; i > 0 && s.ch != quote && s.ch >= 0; i-- {
		d := uint32(digitVal(s.ch))
		if d >= base {
			s.error(s.offset, "illegal character in escape sequence")
			break
		}
		x = x*base + d
		s.next()
	}
	// in case of an error, consume remaining chars
	for ; i > 0 && s.ch != quote && s.ch >= 0; i-- {
		s.next()
	}
	if x > max || 0xD800 <= x && x < 0xE000 {
		s.error(offs, "escape sequence is invalid Unicode code point")
	}
}

func (s *Scanner) scanChar() string {
	// '\'' opening already consumed
	offs := s.offset - 1

	n := 0
	for s.ch != '\'' {
		ch := s.ch
		n++
		s.next()
		if ch == '\n' || ch < 0 {
			s.error(offs, "character literal not terminated")
			n = 1
			break
		}
		if ch == '\\' {
			s.scanEscape('\'')
		}
	}

	s.next()

	if n != 1 {
		s.error(offs, "illegal character literal")
	}

	return string(s.src[offs:s.offset])
}

func (s *Scanner) scanString() string {
	// '"' opening already consumed
	offs := s.offset - 1

	for s.ch != '"' {
		ch := s.ch
		s.next()
		if ch == '\n' || ch < 0 {
			s.error(offs, "string not terminated")
			break
		}
		if ch == '\\' {
			s.scanEscape('"')
		}
	}

	s.next()

	return string(s.src[offs:s.offset])
}

func stripCR(b []byte) []byte {
	c := make([]byte, len(b))
	i := 0
	for _, ch := range b {
		if ch != '\r' {
			c[i] = ch
			i++
		}
	}
	return c[:i]
}

func (s *Scanner) scanRawString() string {
	// '`' opening already consumed
	offs := s.offset - 1

	hasCR := false
	for s.ch != '`' {
		ch := s.ch
		s.next()
		if ch == '\r' {
			hasCR = true
		}
		if ch < 0 {
			s.error(offs, "string not terminated")
			break
		}
	}

	s.next()

	lit := s.src[offs:s.offset]
	if hasCR {
		lit = stripCR(lit)
	}

	return string(lit)
}

func (s *Scanner) skipWhitespace() {
	for s.ch == ' ' || s.ch == '\t' || s.ch == '\n' && !s.insertSemi || s.ch == '\r' {
		s.next()
	}
}

// Helper functions for scanning multi-byte tokens such as >> += >>= .
// Different routines recognize different length tok_i based on matches
// of ch_i. If a token ends in '=', the result is tok1 or tok3
// respectively. Otherwise, the result is tok0 if there was no other
// matching character, or tok2 if the matching character was ch2.

func (s *Scanner) switch2(tok0, tok1 token.Token) token.Token {
	if s.ch == '=' {
		s.next()
		return tok1
	}
	return tok0
}

func (s *Scanner) switch3(tok0, tok1 token.Token, ch2 rune, tok2 token.Token) token.Token {
	if s.ch == '=' {
		s.next()
		return tok1
	}
	if s.ch == ch2 {
		s.next()
		return tok2
	}
	return tok0
}

func (s *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Token) token.Token {
	if s.ch == '=' {
		s.next()
		return tok1
	}
	if s.ch == ch2 {
		s.next()
		if s.ch == '=' {
			s.next()
			return tok3
		}
		return tok2
	}
	return tok0
}

// Scan scans the next token and returns the token position, the token,
// and its literal string if applicable. The source end is indicated by
// token.EOF.
//
// If the returned token is a literal (token.IDENT, token.INT, token.FLOAT,
// token.IMAG, token.CHAR, token.STRING) or token.COMMENT, the literal string
// has the corresponding value.
//
// If the returned token is a keyword, the literal string is the keyword.
//
// If the returned token is token.SEMICOLON, the corresponding
// literal string is ";" if the semicolon was present in the source,
// and "\n" if the semicolon was inserted because of a newline or
// at EOF.
//
// If the returned token is token.ILLEGAL, the literal string is the
// offending character.
//
// In all other cases, Scan returns an empty literal string.
//
// For more tolerant parsing, Scan will return a valid token if
// possible even if a syntax error was encountered. Thus, even
// if the resulting token sequence contains no illegal tokens,
// a client may not assume that no error occurred. Instead it
// must check the scanner's ErrorCount or the number of calls
// of the error handler, if there was one installed.
//
// Scan adds line information to the file added to the file
// set with Init. Token positions are relative to that file
// and thus relative to the file set.
//
func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
scanAgain:
	s.skipWhitespace()

	// current token start
	pos = s.file.Pos(s.offset)

	// determine token value
	insertSemi := false
	switch ch := s.ch; {
	case isLetter(ch):
		lit = s.scanIdentifier()
		if len(lit) > 1 {
			// keywords are longer than one letter - avoid lookup otherwise
			tok = token.Lookup(lit)
			switch tok {
			case token.IDENT, token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN:
				insertSemi = true
			}
		} else {
			insertSemi = true
			tok = token.IDENT
		}
	case '0' <= ch && ch <= '9':
		insertSemi = true
		tok, lit = s.scanNumber(false)
	default:
		s.next() // always make progress
		switch ch {
		case -1:
			if s.insertSemi {
				s.insertSemi = false // EOF consumed
				return pos, token.SEMICOLON, "\n"
			}
			tok = token.EOF
		case '\n':
			// we only reach here if s.insertSemi was
			// set in the first place and exited early
			// from s.skipWhitespace()
			s.insertSemi = false // newline consumed
			return pos, token.SEMICOLON, "\n"
		case '"':
			insertSemi = true
			tok = token.STRING
			lit = s.scanString()
		case '\'':
			insertSemi = true
			tok = token.CHAR
			lit = s.scanChar()
		case '`':
			insertSemi = true
			tok = token.STRING
			lit = s.scanRawString()
		case ':':
			tok = s.switch2(token.COLON, token.DEFINE)
		case '.':
			if '0' <= s.ch && s.ch <= '9' {
				insertSemi = true
				tok, lit = s.scanNumber(true)
			} else if s.ch == '.' {
				s.next()
				if s.ch == '.' {
					s.next()
					tok = token.ELLIPSIS
				}
			} else {
				tok = token.PERIOD
			}
		case ',':
			tok = token.COMMA
		case ';':
			tok = token.SEMICOLON
			lit = ";"
		case '(':
			tok = token.LPAREN
		case ')':
			insertSemi = true
			tok = token.RPAREN
		case '[':
			tok = token.LBRACK
		case ']':
			insertSemi = true
			tok = token.RBRACK
		case '{':
			tok = token.LBRACE
		case '}':
			insertSemi = true
			tok = token.RBRACE
		case '+':
			tok = s.switch3(token.ADD, token.ADD_ASSIGN, '+', token.INC)
			if tok == token.INC {
				insertSemi = true
			}
		case '-':
			tok = s.switch3(token.SUB, token.SUB_ASSIGN, '-', token.DEC)
			if tok == token.DEC {
				insertSemi = true
			}
		case '*':
			tok = s.switch2(token.MUL, token.MUL_ASSIGN)
		case '/':
			if s.ch == '/' || s.ch == '*' {
				// comment
				if s.insertSemi && s.findLineEnd() {
					// reset position to the beginning of the comment
					s.ch = '/'
					s.offset = s.file.Offset(pos)
					s.rdOffset = s.offset + 1
					s.insertSemi = false // newline consumed
					return pos, token.SEMICOLON, "\n"
				}
				lit = s.scanComment()
				if s.mode&ScanComments == 0 {
					// skip comment
					s.insertSemi = false // newline consumed
					goto scanAgain
				}
				tok = token.COMMENT
			} else {
				tok = s.switch2(token.QUO, token.QUO_ASSIGN)
			}
		case '%':
			tok = s.switch2(token.REM, token.REM_ASSIGN)
		case '^':
			tok = s.switch2(token.XOR, token.XOR_ASSIGN)
		case '<':
			if s.ch == '-' {
				s.next()
				tok = token.ARROW
			} else {
				tok = s.switch4(token.LSS, token.LEQ, '<', token.SHL, token.SHL_ASSIGN)
			}
		case '>':
			tok = s.switch4(token.GTR, token.GEQ, '>', token.SHR, token.SHR_ASSIGN)
		case '=':
			tok = s.switch2(token.ASSIGN, token.EQL)
		case '!':
			tok = s.switch2(token.NOT, token.NEQ)
		case '&':
			if s.ch == '^' {
				s.next()
				tok = s.switch2(token.AND_NOT, token.AND_NOT_ASSIGN)
			} else {
				tok = s.switch3(token.AND, token.AND_ASSIGN, '&', token.LAND)
			}
		case '|':
			tok = s.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR)
		default:
			// next reports unexpected BOMs - don't repeat
			if ch != bom {
				s.error(s.file.Offset(pos), fmt.Sprintf("illegal character %#U", ch))
			}
			insertSemi = s.insertSemi // preserve insertSemi info
			tok = token.ILLEGAL
			lit = string(ch)
		}
	}
	if s.mode&dontInsertSemis == 0 {
		s.insertSemi = insertSemi
	}

	return
}

redpajama_set_name: RedPajamaGithub


text:
Service module for ui.router. Let's you watch for certain state changes, waits for confirmation and executes/routes depending on confirmation result.
Currently untested. Use with caution.
# Usage:
Coming soon
# Testing:
Coming soon


text:
.class Lcom/android/server/AlarmManagerService$ScreenReceiver;
.super Landroid/content/BroadcastReceiver;
.source "AlarmManagerService.java"

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/android/server/AlarmManagerService;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = "ScreenReceiver"
.end annotation

# instance fields
.field mLockObj:Ljava/lang/Object;

.field final synthetic this$0:Lcom/android/server/AlarmManagerService;

# direct methods
.method public constructor <init>(Lcom/android/server/AlarmManagerService;)V
    .locals 2

    .prologue
    .line 2460
    iput-object p1, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    invoke-direct {p0}, Landroid/content/BroadcastReceiver;-><init>()V

    .line 2461
    new-instance v0, Landroid/content/IntentFilter;

    const-string v1, "android.intent.action.SCREEN_ON"

    invoke-direct {v0, v1}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V

    .line 2462
    .local v0, "SRfilter":Landroid/content/IntentFilter;
    const-string v1, "android.intent.action.SCREEN_OFF"

    invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V

    .line 2463
    invoke-static {}, Lcom/android/server/AlarmManagerService;->isQuickbootSupported()Z

    move-result v1

    if-eqz v1, :cond_0

    .line 2464
    const-string v1, "com.htc.intent.action.QUICKBOOT_POWEROFF"

    invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V

    .line 2466
    :cond_0
    invoke-virtual {p1}, Lcom/android/server/AlarmManagerService;->getContext()Landroid/content/Context;

    move-result-object v1

    invoke-virtual {v1, p0, v0}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;

    .line 2467
    return-void
.end method

# virtual methods
.method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V
    .locals 10
    .param p1, "context"    # Landroid/content/Context;
    .param p2, "intent"    # Landroid/content/Intent;

    .prologue
    const/4 v7, 0x1

    const/4 v6, 0x0

    .line 2472
    invoke-virtual {p2}, Landroid/content/Intent;->getAction()Ljava/lang/String;

    move-result-object v0

    .line 2473
    .local v0, "action":Ljava/lang/String;
    const-string v5, "android.intent.action.SCREEN_ON"

    invoke-virtual {v0, v5}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v5

    if-eqz v5, :cond_1

    .line 2474
    sput-boolean v7, Lcom/android/server/AlarmManagerService;->isScreenOn:Z

    .line 2476
    const-string v5, "AlarmManager"

    const-string v6, "ACTION_SCREEN_ON"

    invoke-static {v5, v6}, Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 2477
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    iget-object v6, v5, Lcom/android/server/AlarmManagerService;->mLock:Ljava/lang/Object;

    monitor-enter v6

    .line 2478
    :try_start_0
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # invokes: Lcom/android/server/AlarmManagerService;->dumpBlockedAlarmsLocked()V
    invoke-static {v5}, Lcom/android/server/AlarmManagerService;->access$1600(Lcom/android/server/AlarmManagerService;)V

    .line 2479
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # invokes: Lcom/android/server/AlarmManagerService;->recoverBlockedAlarmsLocked()V
    invoke-static {v5}, Lcom/android/server/AlarmManagerService;->access$1200(Lcom/android/server/AlarmManagerService;)V

    .line 2482
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # invokes: Lcom/android/server/AlarmManagerService;->recoverEPSScreenOffBlockedAlarmsLocked()V
    invoke-static {v5}, Lcom/android/server/AlarmManagerService;->access$1700(Lcom/android/server/AlarmManagerService;)V

    .line 2484
    monitor-exit v6

    .line 2521
    :cond_0
    :goto_0
    return-void

    .line 2484
    :catchall_0
    move-exception v5

    monitor-exit v6
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    throw v5

    .line 2485
    :cond_1
    const-string v5, "android.intent.action.SCREEN_OFF"

    invoke-virtual {v0, v5}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v5

    if-eqz v5, :cond_4

    .line 2486
    sput-boolean v6, Lcom/android/server/AlarmManagerService;->isScreenOn:Z

    .line 2487
    const-string v5, "AlarmManager"

    const-string v6, "ACTION_SCREEN_OFF"

    invoke-static {v5, v6}, Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 2489
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # getter for: Lcom/android/server/AlarmManagerService;->mConnectStateLock:Ljava/lang/Object;
    invoke-static {v5}, Lcom/android/server/AlarmManagerService;->access$1800(Lcom/android/server/AlarmManagerService;)Ljava/lang/Object;

    move-result-object v6

    monitor-enter v6

    .line 2490
    :try_start_1
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    invoke-static {}, Landroid/os/SystemClock;->elapsedRealtime()J

    move-result-wide v8

    # setter for: Lcom/android/server/AlarmManagerService;->mScreenOffElapsedTime:J
    invoke-static {v5, v8, v9}, Lcom/android/server/AlarmManagerService;->access$1902(Lcom/android/server/AlarmManagerService;J)J

    .line 2491
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    const/4 v7, 0x1

    # setter for: Lcom/android/server/AlarmManagerService;->mCurrentDataConnectState:Z
    invoke-static {v5, v7}, Lcom/android/server/AlarmManagerService;->access$2002(Lcom/android/server/AlarmManagerService;Z)Z

    .line 2492
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    const/4 v7, 0x1

    # setter for: Lcom/android/server/AlarmManagerService;->mCurrentWifiConnectState:Z
    invoke-static {v5, v7}, Lcom/android/server/AlarmManagerService;->access$2102(Lcom/android/server/AlarmManagerService;Z)Z

    .line 2494
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    invoke-virtual {v5}, Lcom/android/server/AlarmManagerService;->getContext()Landroid/content/Context;

    move-result-object v5

    const-string v7, "connectivity"

    invoke-virtual {v5, v7}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;

    move-result-object v1

    check-cast v1, Landroid/net/ConnectivityManager;

    .line 2496
    .local v1, "cm":Landroid/net/ConnectivityManager;
    if-eqz v1, :cond_2

    invoke-virtual {v1}, Landroid/net/ConnectivityManager;->getMobileDataEnabled()Z

    move-result v5

    if-nez v5, :cond_2

    .line 2497
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    const/4 v7, 0x0

    # setter for: Lcom/android/server/AlarmManagerService;->mCurrentDataConnectState:Z
    invoke-static {v5, v7}, Lcom/android/server/AlarmManagerService;->access$2002(Lcom/android/server/AlarmManagerService;Z)Z

    .line 2500
    :cond_2
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    invoke-virtual {v5}, Lcom/android/server/AlarmManagerService;->getContext()Landroid/content/Context;

    move-result-object v5

    const-string v7, "wifi"

    invoke-virtual {v5, v7}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;

    move-result-object v3

    check-cast v3, Landroid/net/wifi/WifiManager;

    .line 2502
    .local v3, "wifi":Landroid/net/wifi/WifiManager;
    if-eqz v3, :cond_3

    invoke-virtual {v3}, Landroid/net/wifi/WifiManager;->isWifiEnabled()Z

    move-result v5

    if-nez v5, :cond_3

    .line 2504
    invoke-virtual {v3}, Landroid/net/wifi/WifiManager;->getWifiState()I

    move-result v4

    .line 2505
    .local v4, "wifiState":I
    const/4 v5, 0x2

    if-eq v4, v5, :cond_3

    .line 2506
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    const/4 v7, 0x0

    # setter for: Lcom/android/server/AlarmManagerService;->mCurrentWifiConnectState:Z
    invoke-static {v5, v7}, Lcom/android/server/AlarmManagerService;->access$2102(Lcom/android/server/AlarmManagerService;Z)Z

    .line 2510
    .end local v4    # "wifiState":I
    :cond_3
    const-string v5, "AlarmManager"

    const-string v7, "[AlarmQueuing] screen off now: "

    invoke-static {v5, v7}, Landroid/util/Slog;->i(Ljava/lang/String;Ljava/lang/String;)I

    .line 2511
    const-string v5, "AlarmManager"

    new-instance v7, Ljava/lang/StringBuilder;

    invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V

    const-string v8, "[AlarmQueuing] data connection: "

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v7

    iget-object v8, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # getter for: Lcom/android/server/AlarmManagerService;->mCurrentDataConnectState:Z
    invoke-static {v8}, Lcom/android/server/AlarmManagerService;->access$2000(Lcom/android/server/AlarmManagerService;)Z

    move-result v8

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Z)Ljava/lang/StringBuilder;

    move-result-object v7

    invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v7

    invoke-static {v5, v7}, Landroid/util/Slog;->i(Ljava/lang/String;Ljava/lang/String;)I

    .line 2512
    const-string v5, "AlarmManager"

    new-instance v7, Ljava/lang/StringBuilder;

    invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V

    const-string v8, "[AlarmQueuing] wifi connection: "

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v7

    iget-object v8, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # getter for: Lcom/android/server/AlarmManagerService;->mCurrentWifiConnectState:Z
    invoke-static {v8}, Lcom/android/server/AlarmManagerService;->access$2100(Lcom/android/server/AlarmManagerService;)Z

    move-result v8

    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Z)Ljava/lang/StringBuilder;

    move-result-object v7

    invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v7

    invoke-static {v5, v7}, Landroid/util/Slog;->i(Ljava/lang/String;Ljava/lang/String;)I

    .line 2513
    monitor-exit v6

    goto/16 :goto_0

    .end local v1    # "cm":Landroid/net/ConnectivityManager;
    .end local v3    # "wifi":Landroid/net/wifi/WifiManager;
    :catchall_1
    move-exception v5

    monitor-exit v6
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_1

    throw v5

    .line 2515
    :cond_4
    invoke-static {}, Lcom/android/server/AlarmManagerService;->isQuickbootSupported()Z

    move-result v5

    if-eqz v5, :cond_0

    const-string v5, "com.htc.intent.action.QUICKBOOT_POWEROFF"

    invoke-virtual {v0, v5}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v5

    if-eqz v5, :cond_0

    .line 2516
    sput-boolean v6, Lcom/android/server/AlarmManagerService;->isScreenOn:Z

    .line 2517
    new-instance v2, Landroid/content/Intent;

    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    # getter for: Lcom/android/server/AlarmManagerService;->ALARM_FRAMEWORK_BROADCAST_ACTION_QUICKBOOT_POWEROFF:Ljava/lang/String;
    invoke-static {v5}, Lcom/android/server/AlarmManagerService;->access$2200(Lcom/android/server/AlarmManagerService;)Ljava/lang/String;

    move-result-object v5

    invoke-direct {v2, v5}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V

    .line 2518
    .local v2, "intent_quickboot_poweroff":Landroid/content/Intent;
    iget-object v5, p0, Lcom/android/server/AlarmManagerService$ScreenReceiver;->this$0:Lcom/android/server/AlarmManagerService;

    invoke-virtual {v5}, Lcom/android/server/AlarmManagerService;->getContext()Landroid/content/Context;

    move-result-object v5

    sget-object v6, Landroid/os/UserHandle;->ALL:Landroid/os/UserHandle;

    invoke-virtual {v5, v2, v6}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

    .line 2519
    const-string v5, "AlarmManager"

    const-string v6, "ALARM_FRAMEWORK_BROADCAST_ACTION_QUICKBOOT_POWEROFF"

    invoke-static {v5, v6}, Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I

    goto/16 :goto_0
.end method


text:
package uk.ac.ebi.embl.api.validation.fixer.entry;

import uk.ac.ebi.embl.api.entry.Entry;
import uk.ac.ebi.embl.api.entry.location.CompoundLocation;
import uk.ac.ebi.embl.api.entry.location.Location;
import uk.ac.ebi.embl.api.entry.qualifier.AnticodonQualifier;
import uk.ac.ebi.embl.api.entry.qualifier.Qualifier;
import uk.ac.ebi.embl.api.entry.sequence.Segment;
import uk.ac.ebi.embl.api.entry.sequence.SegmentFactory;
import uk.ac.ebi.embl.api.validation.Origin;
import uk.ac.ebi.embl.api.validation.SequenceEntryUtils;
import uk.ac.ebi.embl.api.validation.Severity;
import uk.ac.ebi.embl.api.validation.ValidationEngineException;
import uk.ac.ebi.embl.api.validation.ValidationException;
import uk.ac.ebi.embl.api.validation.ValidationMessage;
import uk.ac.ebi.embl.api.validation.ValidationResult;
import uk.ac.ebi.embl.api.validation.annotation.Description;
import uk.ac.ebi.embl.api.validation.check.entry.EntryValidationCheck;
import uk.ac.ebi.embl.api.validation.helper.location.LocationToStringCoverter;

import java.util.ArrayList;

@Description("Sequence has been added to the anticodon value : \"{0}\""
		+ "Illegal amino acid \"{0}\" changed to legal amino acid \"{1}\"")
public class AnticodonQualifierFix extends EntryValidationCheck
{
	private final static String SEQUENCE_FIX_ID = "AnticodonQualifierFix_1";
	private final static String AMINO_ACID_FIX_ID = "AnticodonQualifierFix_2";

	public AnticodonQualifierFix()
	{
	}

	public ValidationResult check(Entry entry) throws ValidationEngineException
	{
		result = new ValidationResult();

		if (entry == null)
		{
			return result;
		}
		if (entry.getSequence() == null)
		{
			return result;
		}
		ArrayList<Qualifier> anticodonQualifiers = (ArrayList<Qualifier>) SequenceEntryUtils.getQualifiers(Qualifier.ANTICODON_QUALIFIER_NAME, entry);
		if (anticodonQualifiers.isEmpty())
			return result;
		AnticodonQualifier qualifier =null;
		for (Qualifier anticodonQualifier : anticodonQualifiers)
		{

			qualifier = new AnticodonQualifier(anticodonQualifier.getValue());

			try
			{
				CompoundLocation<Location> location = qualifier.getLocations();
				String pos=LocationToStringCoverter.renderCompoundLocation(location);
				String aminoAcid=qualifier.getAminoAcid()!=null?qualifier.getAminoAcid().getAbbreviation():null;//valid amino acid(e.g. aa: Sec) from the anticodon (e.g. aa :SeC) value
				String aminoAcidString=qualifier.getAminoAcidString();//from the original anticodon value(e.g. aa :SeC)
				SegmentFactory factory = new SegmentFactory();
				Segment segment = (entry.getSequence()!=null && entry.getSequence().getSequenceByte()!=null)?factory.createSegment(entry.getSequence(), location):null;
				if(segment==null)
					continue;
				String sequenceString = new String(segment.getSequenceByte());
				String anticodonValue = qualifier.getValue(pos,aminoAcid,sequenceString);

				if(aminoAcid!=null&&!aminoAcidString.equals(aminoAcid))
				{
					reportMessage(Severity.FIX, anticodonQualifier.getOrigin(), AMINO_ACID_FIX_ID, aminoAcidString, aminoAcid);
				}
				if(qualifier.getSequence()==null)
				{
					reportMessage(Severity.FIX, anticodonQualifier.getOrigin(), SEQUENCE_FIX_ID, anticodonValue);
				}
				anticodonQualifier.setValue(anticodonValue);

			} catch (ValidationException e)
			{
              reportException(result, e,qualifier);
			}
			catch(Exception e)
			{
				throw new ValidationEngineException(e);
			}

		}
		return result;
	}

	private void reportException(ValidationResult result, ValidationException exception,Qualifier qualifier)
	{
		ValidationMessage<Origin> message = exception.getValidationMessage();
		message.append(qualifier.getOrigin());
		result.append(message);
	}
}


text:
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Queries</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../../index.html" title="Chapter 1. Geometry">
<link rel="up" href="../spatial_indexes.html" title="Spatial Indexes">
<link rel="prev" href="creation_and_modification.html" title="Creation and Modification">
<link rel="next" href="rtree_examples.html" title="Examples">

Home
Libraries
People
FAQ
More

Queries

        Queries returns Values which meets some predicates. Currently
        supported are three types of predicates:

            spatial predicates - spatial conditions that must be met by stored Value
            and some Geometry,

            distance predicates - distance conditions that must be met by stored
            Value and some Geometry,

            user-defined unary predicate - function, function object or lambda expression
            checking user-defined condition.

        For example queries may be used to retrieve Values:

            intersecting some area but not within other area,

            are nearest to some point,

            overlapping a box and has user-defined property.

        Performing
        a query

        There are three ways to perform a query presented below. All of them returns
        Values intersecting some region defined as a Box.

        Method call

std::vector<Value> returned_values;
Box box_region(...);
rt.query(bgi::intersects(box_region), std::back_inserter(returned_values));

        Function call

std::vector<Value> returned_values;
Box box_region(...);
index::query(rt, bgi::intersects(box_region), std::back_inserter(returned_values));

        Use of pipe operator generating a range

Box box_region(...);
BOOST_FOREACH(Value & v, rt | index::adaptors::queried(bgi::intersects(box_region)))
  ; // do something with v

        Spatial
        predicates

        Queries using spatial predicates returns Values which are related
        somehow to some Geometry - box, polygon, etc. Names of spatial predicates
        correspond to names of Boost.Geometry algorithms. Examples of some basic
        queries may be found in tables below. The query region and result Values are orange.

<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>

                  intersects(Box)

                  covered_by(Box)

                  disjoint(Box)

                  overlaps(Box)

                  within(Box)

<colgroup>
<col>
<col>
<col>
</colgroup>

                  intersects(Ring)

                  intersects(Polygon)

                  intersects(MultiPolygon)

        To use a spatial predicate one may use one of the functions defined in boost::geometry::index namespace.

rt.query(index::intersects(box), std::back_inserter(result));
rt.query(index::covered_by(box), std::back_inserter(result));
rt.query(index::disjont(box), std::back_inserter(result));
rt.query(index::overlaps(box), std::back_inserter(result));
rt.query(index::within(box), std::back_inserter(result));

        All spatial predicates may be negated, e.g.:

rt.query(!index::intersects(box), std::back_inserter(result));
// the same as
rt.query(index::disjoint(box), std::back_inserter(result));

        Distance predicates

        Nearest
        neighbours queries

        Nearest neighbours queries returns Values which are closest
        to some point in space. Additionally it is possible to define how the distance
        to the Value should be calculated.
        The example of knn query is presented below. 5 Values nearest
        to some point are orange.

        k nearest
        neighbours

        There are three ways of performing knn queries. Following queries returns
        k Values closest
        to some point in space. For Boxes Indexables the
        distance to the nearest point is calculated by default.

        Method call

std::vector<Value> returned_values;
Point pt(...);
rt.query(index::nearest(pt, k), std::back_inserter(returned_values));

        Function call

std::vector<Value> returned_values;
Point pt(...);
index::query(rt, index::nearest(pt, k), std::back_inserter(returned_values));

        Use of operator |

Point pt(...);
BOOST_FOREACH(Value & v, rt | index::adaptors::queried(index::nearest(pt, k)))
  ; // do something with v

        User-defined
        unary predicate

        The user may pass a UnaryPredicate
        - function, function object or lambda expression taking const reference to
        Value and returning bool. This object may be passed to the query in order
        to check if Value should be returned by the query. To do it
        one may use index::satisfies()
        function like on the example below:

bool is_red(Value const& v)
{
  return v.is_red();
}

struct is_red_o
{
  template <typename Value>
  bool operator()(Value const& v)
  {
    return v.is_red();
  }
}

// ...

rt.query(index::intersects(box) && index::satisfies(is_red),
         std::back_inserter(result));

rt.query(index::intersects(box) && index::satisfies(is_red_o()),
         std::back_inserter(result));

#ifndef BOOST_NO_CXX11_LAMBDAS
rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }),
         std::back_inserter(result));
#endif

        satisfies()
        may be negated, e.g.:

bool is_red(Value const& v) { return v.is_red(); }
bool is_not_red(Value const& v) { return !v.is_red(); }

// ...

rt.query(index::intersects(box) && index::satisfies(is_red),
         std::back_inserter(result));
// the same as
rt.query(index::intersects(box) && !index::satisfies(is_not_red),
         std::back_inserter(result));

        Passing
        a set of predicates

        It's possible to use some number of predicates in one query by connecting
        them with operator&&
        e.g. Pred1 &&
        Pred2 &&
        Pred3 &&
        ....

        These predicates are connected by logical AND. Passing all predicates together
        not only makes possible to construct advanced queries but is also faster
        than separate calls because the tree is traversed only once. Traversing is
        continued and Values are
        returned only if all predicates are met. Predicates are checked left-to-right
        so placing most restrictive predicates first should accelerate the search.

rt.query(index::intersects(box1) && !index::within(box2),
         std::back_inserter(result));

rt.query(index::intersects(box1) && !index::within(box2) && index::overlaps(box3),
         std::back_inserter(result));

        Of course it's possible to connect different types of predicates together.

index::query(rt, index::nearest(pt, k) && index::within(b), std::back_inserter(returned_values));

BOOST_FOREACH(Value & v, rt | index::adaptors::queried(index::nearest(pt, k) && index::covered_by(b)))
  ; // do something with v

        Inserting
        query results into the other R-tree

        There are several ways of inserting Values returned by a query to the other
        R-tree container. The most basic way is creating a temporary container for
        Values and insert them later.

namespace bgi = boost::geometry::index;
typedef std::pair<Box, int> Value;
typedef bgi::rtree< Value, bgi::linear<32, 8> > RTree;

RTree rt1;
/* some inserting into the tree */

std::vector<Value> result;
rt1.query(bgi::intersects(Box(/*...*/)), std::back_inserter(result));
RTree rt2(result.begin(), result.end());

        However there are better ways. One of these methods is mentioned in the "Creation
        and modification" section. The insert iterator may be passed directly
        into the query.

RTree rt3;
rt1.query(bgi::intersects(Box(/*...*/))), bgi::inserter(rt3));

        If you like Boost.Range you'll appreciate the third option. You may pass
        the result Range directly into the constructor.

RTree rt4(rt1 | bgi::adaptors::queried(bgi::intersects(Box(/*...*/)))));

Copyright © 2009-2013 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz

        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)


text:
package com.uchuhimo.inline;

public class Inline {
  public static void main(String[] args) {
    InlineKt.testInline();
  }
}


text: console.log("inline file");


text:
title: Second
version: 1.0.0
signature: |
  moment().second(Number);
  moment().second(); // Number
  moment().seconds(Number);
  moment().seconds(); // Number
---

Gets or sets the seconds.

Accepts numbers from 0 to 59. If the range is exceeded, it will bubble up to the minutes.