Git Product home page Git Product logo

winmd's Introduction

Build Status

C++ winmd parser

A winmd parser written in C++ and based on the ECMA-335 standard. This winmd parser powers C++/WinRT.

The C++ winmd parser is part of the xlang family of projects that help developers create APIs that can run on multiple platforms and be used with a variety of languages.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

winmd's People

Contributors

alvinhochun avatar asklar avatar defaultryan avatar dunhor avatar kennykerr avatar manodasanw avatar microsoft-github-operations[bot] avatar microsoftopensource avatar reflectronic avatar scottj1s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

winmd's Issues

Need docs

It would be great to have docs on how to use this library. Some things I've noticed that weren't obvious to me as a first time user of the library:

  1. things that return std::pair<T, T> like db.PropertyList() as a way to enable range-based loops. This is cool but non-obvious, we should document it
  2. Getting enum values from an enum isn't super obvious (there is a get_enumerator if you follow the intellisense but that's not the right thing to use). Also, you need to make sure you are getting the constant value based on the right underlying type (int vs. uint). This can be determined based on value.Signature().Type().element_type() == ElementType::U4 for WinRT
  3. Some entries don't behave gracefully and crash or throw if you call APIs on them, e.g. the type crashes when doing is_enum on it. These can be filtered out based on e.g. SpecialName()
  4. Hard to figure out if something is a struct or not.
  5. Guidance on should I use the db or the cache?

(lots more to come :) )

Error messages regarding unresolved typeref for custom attribute params doesn't include the details of the type

impl::throw_invalid("CustomAttribute named param referenced unresolved enum type");

This is a simple string that says "something" went wrong and I'm not gonna tell ya. Na na nan na nana!

This sort of thing is frustrating for a user as they have no clue what it is referring to. All the information should be there in the code to form a much better message that includes the FQN for the unresolved type, it should also have the module reference to identify what module the type is supposed to come from. This would make resolving such errors WAY easier.

impl/base.h is not namespaced

When you add the winmd package to your include directories and your project already contains it's own "impl/base.h" header file, it causes problems.

This could be solved by moving everything in impl up a directory level and removing the impl folder and renaming base.h to winmd_base.h.

Readme needed

Readme should be fleshed out:

  • Add link to xlang repo (which in turn should have its readme modified to point back here)
  • Add link to nuget package
  • Include build pipeline badge

see also:
microsoft/xlang#513

reader::filter can't handle two excludes of the same length

The comparison predicate in reader::filter is attempting to order items in descending order of string length, and breaks ties by putting the true booleans before the false booleans.

The problem is that the predicate is ill-formed. A comparison predicate should always return false for compare(a, a) and should return false for at least one of compare(a, b) and compare(b, a). To put it another way, if compare(a, a) ever returned true, or compare(a, b) and compare(b, a) both returned true, you have an ill-formed predicate.

The filter predicate gets into this situation when there are two entries in exclude with the same string length, causing misbehavior in release and an assert in debug.

The predicate to sort needs to be updated from

return (size_compare > 0) || ((size_compare == 0) && !lhs.second);

to

return (size_compare > 0) || ((size_compare == 0) && lhs.first && !lhs.second);

need ability for filter to match exact type names

for the swift/winrt language projection, we need the ability to filter out exact type names, and not just lazy matching by the beginning of the string. this means changing the implementation of filter::match from this:

        static bool match(std::string_view const& type_namespace, std::string_view const& type_name, std::string_view const& match) noexcept
        {
            if (match.size() <= type_namespace.size())
            {
                return impl::starts_with(type_namespace, match);
            }

            if (!impl::starts_with(match, type_namespace))
            {
                return false;
            }
            if (match[type_namespace.size()] != '.')
            {
                return false;
            }
            return impl::starts_with(type_name, match.substr(type_namespace.size() + 1));
        }

to

        static bool match(std::string_view const& type_namespace, std::string_view const& type_name, std::string_view const& match, bool exact) noexcept
        {
            if (match.size() <= type_namespace.size())
            {
                if (exact)
                {
                    return type_namespace == match;
                }
                return impl::starts_with(type_namespace, match);
            }

            if (!impl::starts_with(match, type_namespace))
            {
                return false;
            }
            if (match[type_namespace.size()] != '.')
            {
                return false;
            }

            if (exact)
            {
                return type_name == match.substr(type_namespace.size() + 1);
            }
            return impl::starts_with(type_name, match.substr(type_namespace.size() + 1));
        }

IWebSocket extends IClosable but in the `MethodList` there's no `void Close()` defined

Not quite certain if this is the problem of winmd parser, or of the Windows.winmd file, but as the title suggests, to me the type is illy defined. I'm working on something pretty much like NodeRT and am trying to export the whole WinRT world to the TypeScript definition file, the following is what I got just by range-foring the type.MethodList():

export interface IWebSocket extends Windows.Foundation.IClosable {
    outputStream: Windows.Storage.Streams.IOutputStream;
    connectAsync(uri: Windows.Foundation.Uri): Windows.Foundation.IAsyncAction;
    setRequestHeader(headerName: string, headerValue: string): void;
    closed(eventHandler: Windows.Foundation.TypedEventHandler<Windows.Networking.Sockets.IWebSocket, Windows.Networking.Sockets.WebSocketClosedEventArgs>): any;
    close(code: number, reason: string): void;
}

Verified other class/interface definitions which implements/extends IClosable and there is such definition available, and now I make IWebSocket as a special case. Am I missing something here?

Can't access a generic struct

In my WinMD there is a method that returns IList<MyStruct>. This shows up as a TypeRef and I get IVector`1 and GenericTypeInstSig.gt.GenericArgCount() == 1, however GenericTypeInstSig.GenericArgs() is empty

Debugged this via TTT - it turns out my code was doing something like:

  if (method.Signature().ReturnType()) {
    const auto& type = method.Signature().ReturnType().Type();
    returnType = GetType(type);
  }
  // ...
  for (const auto& param : signature.Params()) {
    // ...
  }

The line where I get the Type() via const auto& was causing the generic params (along other temporaries on that line) to destroy at the end of the line. This can be fixed by removing the & from my code but I think this might be a bug still?

calling is_enum on an interface typedef throws an exception

  for (auto const& type : db.TypeDef) {
    std::cout << (type.is_enum() ? "enum " : "class ") << type.TypeName() << std::endl;
...
  }

winmd2markdown.exe!winmd::impl::throw_invalid(const std::string & message) Line 47 C++
winmd2markdown.exe!winmd::reader::table_base::get_value(const unsigned int row, const unsigned int column) Line 43 C++
winmd2markdown.exe!winmd::reader::row_basewinmd::reader::TypeDef::get_string(const unsigned int column) Line 545 C++
winmd2markdown.exe!winmd::reader::TypeDef::TypeNamespace() Line 61 C++
winmd2markdown.exe!winmd::reader::get_type_namespace_and_name(const winmd::reader::coded_index & type) Line 9 C++
winmd2markdown.exe!winmd::reader::get_base_class_namespace_and_name(const winmd::reader::TypeDef & type) Line 25 C++
winmd2markdown.exe!winmd::reader::extends_type(winmd::reader::TypeDef type, std::basic_string_view<char,std::char_traits> typeNamespace, std::basic_string_view<char,std::char_traits> typeName) Line 30 C++
winmd2markdown.exe!winmd::reader::TypeDef::is_enum() Line 119 C++
winmd2markdown.exe!main() Line 56 C++

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.