Giter Site home page Giter Site logo

crystalline's Introduction

crystalline

A Language Server for Crystal.

Build Status GitHub tag (latest SemVer) GitHub

Crystalline is an implementation of the Language Server Protocol written in and for the Crystal Language. It aims to provide limited language features (like go-to, autocompletion, syntax and semantic checking) and ease development with any compatible code editor.

Status: in development.


Installation

Recommended method is to download and use pre-built binaries when possible. Building from source does take a long time.

Compatibility

Crystal Crystalline
1.13 0.14
1.12 0.13
1.11 0.12
1.10 0.11
1.9 0.10
1.8 0.9
1.7 0.8
1.6 0.7
1.4 0.6
1.3 0.5
1.2 0.4
1.1 0.4
1.0 0.3
0.36 0.2
0.35.1 0.1

Pre-built binaries

Latest Release

Linux (x86_64)
wget https://github.com/elbywan/crystalline/releases/latest/download/crystalline_x86_64-unknown-linux-musl.gz -O crystalline.gz &&\
gzip -d crystalline.gz &&\
chmod u+x crystalline
ArchLinux
yay -S crystalline
MacOS

Install using homebrew:

brew install crystalline

Specific release

See the releases page.

Specific commit

Binaries are uploaded as artifacts during the CI build.

Build from source

Warning: this can take a long time! (several minutes - up to 20 minutes, depending on your hardware)

Scoped install

In the .shard.yml file:

development_dependencies:
  crystalline:
    github: elbywan/crystalline
    branch: master

Then:

# Produces a binary at ./bin/crystalline
shards build crystalline --release --no-debug --progress -Dpreview_mt

Global install

git clone https://github.com/elbywan/crystalline
cd crystalline
shards install
mkdir bin
crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug --progress -Dpreview_mt

Known Build Issues

Potential errors when building from source.

llvm-config path

llvm is required in order to build crystalline, if you get the following error message it means that the crystal compiler is unable to locate the llvm-config binary:

--: : command not found
Showing last frame. Use --error-trace for full trace.

In /usr/local/Cellar/crystal/0.35.1/src/llvm/lib_llvm.cr:13:17

 13 | VERSION = {{`#{LibLLVM::LLVM_CONFIG} --version`.chomp.stringify}}
                  ^
Error: error executing command: "" --version, got exit status 127

This can be solved by adding the location of the llvm-config binary to the LLVM_CONFIG environment variable. (or the containing directory to the PATH env. variable)

For instance on a typical macOS setup, prefixing the command with the following declaration would solve the issue:

# Prepend the command with this:
env LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config
# For Example:
env LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug -Dpreview_mt

Replace env by export on Debian and derived (Ubuntu, Mint, ...)

ld: library not found for -llibxml2.tbd

LLVM 10.0.1 has some issues when reporting required system libraries on macOS.

More info: here

# Wrong: -llibxml2.tbd
$ llvm-config --system-libs
-lm -lz -lcurses -llibxml2.tbd
# `liblibxml2.tbd.dylib` is unlikely to be found during compilation,
# hence the "library not found" errorโ€ฆ

A hacky solution until llvm produces a solution would be to add a symbolic link to the correct shared library file:

ln -s /usr/lib/libxml2.2.dylib /usr/local/lib/liblibxml2.tbd.dylib

Or just use a different LLVM major version until this issue is fixed upstream.

Usage

Crystalline is meant to be used alongside an editor extension.

VSCode

vscode screen

  • Reload the window by pressing CMD/CTRL + SHIFT + P and select Developer: Reload Window (or as an alternative, restart VSCode).

Vim/Neovim

Using Conquer of Completion we can configure Crystalline as our LSP backend and get all the features of Crystalline we would get with VSCode.

  • Download vim-crystal plugin.
  • Download CoC plugin.
  • Make sure crystalline binary is in your PATH.

Add the following snippet to your coc-settings.json file:

{
"languageserver": {
    "crystal": {
      "command": "crystalline",
      "args": [
        "--stdio"
      ],
      "filetypes": [
        "crystal"
      ],
      "rootPatterns": ["shard.yml"]
    }
  }
}

Emacs

  • Download the crystal-mode package.
  • Download the lsp-mode package.
  • Make sure crystalline binary is in your PATH.

At the moment, lsp-mode only knows about scry as the Crystal language server. So, to get it working with crystalline we need to configure lsp-mode to look for crystalline.

You can use the following config snippet to achieve this:

(with-eval-after-load 'lsp-mode
  (add-to-list 'lsp-language-id-configuration
               '(crystal-mode . "crystal"))
  (lsp-register-client
  (make-lsp-client :new-connection (lsp-stdio-connection '("crystalline"))
                   :activation-fn (lsp-activate-on "crystal")
                   :priority '1
                   :server-id 'crystalline)))

This will give higher priority to crystalline, and Emacs should automatically connect to the backend whenever you're in crystal-mode.

Entry point

Important: Crystalline will try to determine which file is best suited as an entry point when providing language features.

The default behaviour is to check the shard.yml file for a target entry with the same name as the shard.

name: my_shard

targets:
  my_shard:
    main: src/entry.cr

With the configuration above, every file required by src/entry.cr will use src/entry.cr as the entry point.

If this shard.yml entry is not present, or if the file is not part of the main dependency tree then crystalline will use the file itself as the entry point.

To override this behaviour, you can add a configuration key in the shard.yml file.

crystalline:
  main: .crystalline_main.cr

This can be extremely important to understand when you are writing a code library that does not call any of its own methods - it will skip code analysis. In this case, and if you are writing specs, you should point to a file that require the specs (or anything calling the library) and then crystalline will use it as the entry point.

# Contents of a file at the root of the project.
# Will require the specs that call the library methods and enable the code analysis.
require "./spec/**"

Multiple projects

If you have multiple Crystal projects in a single folder (e.g. a monorepo), you can add a projects field in the root shard.yml file, containing an array of paths or globs to the underlying Crystal projects:

crystalline:
  projects:
    - projects/my_project_1
    - workspaces/**

Each of these projects must contain the shard.yml, ideally with the entry point as mentioned above. However, even if no entry point is present, requires will still be resolved relative to the project directory rather than the root directory.

Features

Disclaimer: Crystalline is not as extensive in terms of features as other Language Servers but still provides very convenient tools.

Code Diagnostics

Syntax and semantic checks on save.

Limited Autocompletion

List (depending on the target) method definitions, macros or module/class/struct names or symbols available in the current context.

Formatting

A whole document or a text selection.

Go to definition

By clicking on a symbol with the Cmd or Ctrl key pressed (editor/platform dependent).

Hover information

Hovering should display (when possible) either a variable type, a function definition signature or the expanded macro.

Document symbols

Fetch all the symbols in a given file, used in VSCode to populate the Outline view and the Breadcrumbs.

Limitations

  • Memory usage is high due to the boehm GC behaviour and the crystal compiler itself. See: #23

  • Due to Crystal having a wide type inference system (which is incredibly convenient and practical), compilation times can unfortunately be relatively long for big projects and depending on the hardware. This means that the LSP will be stuck waiting for the compiler to finish before being able to provide a response. Crystalline tries to mitigate that by caching compilation outcome when possible.

  • Methods that are not called anywhere will not be analyzed, as this is how the Crystal compiler works.

  • The parser is not permissive, nor incremental which means that the features will sometimes not work. It would involve a massive amount of work to change that.

Development

Dev build

Sentry is used to re-build crystalline in debug mode on code change.

# To build sentry (once):
shards build --release sentry
# Then, to launch it and watch the filesystem:
./bin/sentry -i

Logs

Logging is the most practical way to debug the LSP.

# Use the LSP logger to display logs in the editor.
LSP::Log.info { "log" }

Debug logs are deactivated by default, uncomment this line in src/crystalline/main.cr to enable them:

# Uncomment:
# ::Log.setup(:debug, LSP::Log.backend.not_nil!)

Contributing

  1. Fork it (https://github.com/elbywan/crystalline/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Please always crystal tool format your code!

Credit

  • Scry, the original LSP for Crystal has been a great source of inspiration. I also re-used tiny bits of code from there.
  • Icon made by Smashicons from www.flaticon.com.

Trivia

Why the name crystalline?

Aside of the obvious reasons (crystal-lang), cristaline is a famous bottled water brand in France that published silly TV commercials. It is pronounced the same as crystalline.

guy roux

crystalline's People

Contributors

elbywan avatar hugopl avatar nicolab avatar pgdanes avatar refi64 avatar tarbetu avatar taupiqueur avatar y8 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crystalline's Issues

Crystalline does not build on freebsd.

shards install works fine.

crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug --progress -Dpreview_mt --error-trace

bails out with error

n src/crystalline.cr:1:1l)              

 1 | require "./crystalline/requires"
     ^
Error: while requiring "./crystalline/requires"


In src/crystalline/requires.cr:8:1

 8 | require "compiler/crystal/loader"
     ^
Error: can't find file 'compiler/crystal/loader'

If you're trying to require a shard:
- Did you remember to run `shards install`?
- Did you make sure you're running the compiler in the same directory as your shard.yml?

Allow detection of entrypoint where shard.yml is not at workspace root

In a monorepo setup, the shard.yml may not be at the workspace root, which means that currently crystalline cannot detect the entrypoint. For example:

  • In my specific case, all crystal code exists within the imaginatively named /crystal directory. This contains a shard.yml which defines multiple targets. I deal with the multiple targets by creating a .crystalline_main.cr which requires all code, as suggested in the readme.

  • One could imagine a different setup where a monorepo contained multiple independent crystal codebases, each with their own shard.yml (and in this case the code might not compatible and require-able at the same time).

Is there a way to handle these scenarios in crystalline?

From what I can tell the key starting point is Crystalline::Workspace#compile in https://github.com/elbywan/crystalline/blob/master/src/crystalline/workspace.cr, which has a file_uri? โ€“ I assume this is the current editor file? In this case the implementation of Crystalline::Workspace#entry_point could be changed to take the current file, which should allow implementing some reasonable algorithm for detecting the correct entrypoint.

A few options come to mind:

  1. Add support for an optional .crystalline file, which points to the main shard.yml. This would work for the first setup, but wouldn't handle the second.

  2. Walk up the directory hierarchy from the current file, stopping at the first shard.yaml which is discovered. I'd worry that this would cause issues when inside some shard for example.

  3. Allow an optional .crystalline file to define an array of potential crystal root directories, and then pick one of these to use based on the current editor file.

Do any of the above make sense, or have I missed an existing solution to this problem?

Provide musl based builds

Please provide musl based builds in releases, because some Linux distro can not run glibc binaries (Alpine, Void Linux musl).
A statically linked binary would work both on glibc and musl systems.

LSP delete code before save buffer unexpectedly if there exists syntax error when use crystallize as LSP server.

Following is the log come from emacs lsp client, thank you.

[Trace - 09:36:53 PM] Sending notification 'textDocument/didChange'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr",
    "version": 737
  },
  "contentChanges": [
    {
      "range": {
        "start": {
          "line": 2,
          "character": 0
        },
        "end": {
          "line": 2,
          "character": 2
        }
      },
      "rangeLength": 2,
      "text": ""
    }
  ]
}


[Trace - 09:36:53 PM] Sending request 'textDocument/formatting - (1879)'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr"
  },
  "options": {
    "tabSize": 2,
    "insertSpaces": true
  }
}


[Trace - 09:36:53 PM] Received response 'textDocument/formatting - (1879)' in 0ms.
Result: [
  {
    "range": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 18,
        "character": 0
      }
    },
    "newText": "class Home::IndexPage < AuthLayout\n  def content\n    div class: \"px-4 py-5 my-5 text-center\" do\n      h1 \"CoverApp\", class: \"display-5 fw-bold\"\n      div class: \"col-lg-6 mx-auto\" do\n        para \"It's your lucky day! See a fortune, and share the luck.\", class: \"lead mb-4\"\n        div class: \"d-grid gap-2 d-sm-flex justify-content-sm-center\" do\n          link \"Join\", to: SignUps::New, class: \"btn btn-primary btn-lg px4 me-sm-3\"\n          link \"Login\", to: SignIns::New, class: \"btn btn-outline-secondary btn-lg px-4\"\n        end\n      end\n    end\n    div class: \"container\" do\n      # we will use this later\n    end\n  end\nend\n"
  }
]


[Trace - 09:36:53 PM] Sending notification 'textDocument/didChange'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr",
    "version": 738
  },
  "contentChanges": [
    {
      "range": {
        "start": {
          "line": 0,
          "character": 0
        },
        "end": {
          "line": 18,
          "character": 0
        }
      },
      "rangeLength": 659,
      "text": "class Home::IndexPage < AuthLayout\n  def content\n    div class: \"px-4 py-5 my-5 text-center\" do\n      h1 \"CoverApp\", class: \"display-5 fw-bold\"\n      div class: \"col-lg-6 mx-auto\" do\n        para \"It's your lucky day! See a fortune, and share the luck.\", class: \"lead mb-4\"\n        div class: \"d-grid gap-2 d-sm-flex justify-content-sm-center\" do\n          link \"Join\", to: SignUps::New, class: \"btn btn-primary btn-lg px4 me-sm-3\"\n          link \"Login\", to: SignIns::New, class: \"btn btn-outline-secondary btn-lg px-4\"\n        end\n      end\n    end\n    div class: \"container\" do\n      # we will use this later\n    end\n  end\nend\n"
    }
  ]
}


[Trace - 09:36:53 PM] Sending notification 'textDocument/didSave'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr",
    "version": 738
  }
}


[Trace - 09:36:53 PM] Sending notification 'textDocument/didChange'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr",
    "version": 739
  },
  "contentChanges": [
    {
      "range": {
        "start": {
          "line": 16,
          "character": 3
        },
        "end": {
          "line": 16,
          "character": 3
        }
      },
      "rangeLength": 0,
      "text": "  "
    }
  ]
}


[Trace - 09:36:53 PM] Received request 'window/workDoneProgress/create - (0).
Params: {
  "token": "workspace/compile/284"
}


[Trace - 09:36:53 PM] Sending response 'window/workDoneProgress/create - (0)'. Processing request took 0ms
Params: {
  "jsonrpc": "2.0",
  "id": 0,
  "result": null
}


[Trace - 09:36:53 PM] Received notification '$/progress'.
Params: {
  "token": "workspace/compile/284",
  "value": {
    "title": "Building",
    "message": "/home/zw963/Magpie/clover/src/pages/home/index_page.cr",
    "kind": "begin"
  }
}


[Trace - 09:36:53 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
  "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr",
  "diagnostics": [
    {
      "range": {
        "start": {
          "line": 17,
          "character": 0
        },
        "end": {
          "line": 17,
          "character": 0
        }
      },
      "severity": 1,
      "source": "/home/zw963/Magpie/clover/src/pages/home/index_page.cr",
      "message": "expecting token 'EOF', not 'end'",
      "relatedInformation": []
    }
  ]
}


[Trace - 09:36:53 PM] Received notification '$/progress'.
Params: {
  "token": "workspace/compile/284",
  "value": {
    "message": "Completed with errors.",
    "kind": "end"
  }
}


[Trace - 09:36:54 PM] Sending request 'textDocument/documentSymbol - (1880)'.
Params: {
  "textDocument": {
    "uri": "file:///home/zw963/Magpie/clover/src/pages/home/index_page.cr"
  }
}


[Trace - 09:36:54 PM] Received response 'textDocument/documentSymbol - (1880)' in 382ms.
Result: [
  {
    "name": "Home::IndexPage",
    "kind": 5,
    "range": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 16,
        "character": 2
      }
    },
    "selectionRange": {
      "start": {
        "line": 0,
        "character": 0
      },
      "end": {
        "line": 16,
        "character": 2
      }
    },
    "children": [
      {
        "name": "content",
        "detail": "public content ",
        "kind": 12,
        "range": {
          "start": {
            "line": 1,
            "character": 2
          },
          "end": {
            "line": 15,
            "character": 4
          }
        },
        "selectionRange": {
          "start": {
            "line": 1,
            "character": 2
          },
          "end": {
            "line": 15,
            "character": 4
          }
        },
        "children": []
      }
    ]
  }
]

0.4 fails to compile

Running Manjaro Linux. Got this when doing shards build crystalline --release --no-debug --progress -Dpreview_m on master:

Resolving dependencies
Fetching https://github.com/hugopl/version_from_shard.git
Fetching https://github.com/spider-gazelle/priority-queue.git
Fetching https://github.com/spider-gazelle/bisect.git
Fetching https://github.com/samueleaton/sentry.git
Installing version_from_shard (1.2.4)
Installing bisect (1.2.1)
Installing priority-queue (1.0.1)
Installing sentry (0.3.2 at cd86128)
Building: crystalline
Error target crystalline failed to compile:     
/usr/bin/ld: cannot find /home/sardaukar/.asdf/installs/crystal/1.2.2/share/crystal/src/llvm/ext/llvm_ext.o: No such file or directory
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc "${@}" -o /home/sardaukar/Code/FOREIGN/crystalline/bin/crystalline  -rdynamic -L/home/sardaukar/.asdf/installs/crystal/1.2.2/bin/../lib/crystal -lyaml  /home/sardaukar/.asdf/installs/crystal/1.2.2/share/crystal/src/llvm/ext/llvm_ext.o `"/usr/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre -lm -lgc -lpthread -levent_pthreads -levent  -levent  -lrt -ldl`

Incorrectly reports undefined constants

I have an entry file A, which requires B, C, and D. B and C use types from D, but they're always available since A requires them first. This all compiles fine, but crystallline is complaining about undefined constants referenced in B or C from D. What's weird is that it only starts complaining about that when I save B or C, if I save A (even without changes), its fine again. My shard.yml contains:

targets:
  shapes:
    main: src/A

where A is the appropriate filename.

Is this a bug, if not, is there something I can do to force crystalline to do whatever it does when I save A?

LLVM Build Error

I have no idea with this bunch of LLVM errors. Any missing libs need to be installed?

crystal -v

Crystal 0.35.1 (2020-06-19)

LLVM: 10.0.0
Default target: x86_64-apple-macosx (Catalina 10.15.7)

env LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config crystal build ./src/crystalline.cr -o ./bin/crystalline --release --no-debug -Dpreview_mt

Undefined symbols for architecture x86_64:
  "llvm::ARMInstPrinter::getRegisterName(unsigned int)", referenced from:
      llvm::ARMAsmPrinter::printOperand(llvm::MachineInstr const*, int, llvm::raw_ostream&) in libLLVMARMCodeGen.a(ARMAsmPrinter.cpp.o)
      llvm::ARMAsmPrinter::PrintAsmOperand(llvm::MachineInstr const*, unsigned int, unsigned int, char const*, llvm::raw_ostream&) in libLLVMARMCodeGen.a(ARMAsmPrinter.cpp.o)
      llvm::ARMAsmPrinter::PrintAsmMemoryOperand(llvm::MachineInstr const*, unsigned int, unsigned int, char const*, llvm::raw_ostream&) in libLLVMARMCodeGen.a(ARMAsmPrinter.cpp.o)
  "llvm::ARMInstPrinter::ARMInstPrinter(llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&)", referenced from:
      createARMMCInstPrinter(llvm::Triple const&, unsigned int, llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&) in libLLVMARMDesc.a(ARMMCTargetDesc.cpp.o)
  "llvm::DecodeBLENDMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSHUFMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeSHUFPMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVPERMMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeEXTRQIMask(llvm::MVT, int, int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSHUFBMask(llvm::ArrayRef<unsigned long long>, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSLLDQMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSRLDQMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeUNPCKHMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeUNPCKLMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVPERMVMask(llvm::ArrayRef<unsigned long long>, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVPPERMMask(llvm::ArrayRef<unsigned long long>, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::MetadataTracking::track(void*, llvm::Metadata&, llvm::PointerUnion<llvm::MetadataAsValue*, llvm::Metadata*>)", referenced from:
      llvm::IRBuilderBase::SetInstDebugLocation(llvm::Instruction*) const in llvm_ext.o
  "llvm::DecodeMOVDDUPMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeMOVHLPSMask(unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeMOVLHPSMask(unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePALIGNRMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSHUFHWMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodePSHUFLWMask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::X86ATTInstPrinter::getRegisterName(unsigned int)", referenced from:
      llvm::X86AsmPrinter::PrintAsmOperand(llvm::MachineInstr const*, unsigned int, unsigned int, char const*, llvm::raw_ostream&) in libLLVMX86CodeGen.a(X86AsmPrinter.cpp.o)
      printOperand(llvm::X86AsmPrinter&, llvm::MachineInstr const*, unsigned int, llvm::raw_ostream&, char const*, unsigned int) in libLLVMX86CodeGen.a(X86AsmPrinter.cpp.o)
      llvm::X86AsmPrinter::EmitInstruction(llvm::MachineInstr const*) in libLLVMX86CodeGen.a(X86MCInstLower.cpp.o)
      getShuffleComment(llvm::MachineInstr const*, unsigned int, unsigned int, llvm::ArrayRef<int>) in libLLVMX86CodeGen.a(X86MCInstLower.cpp.o)
  "llvm::AArch64InstPrinter::getRegisterName(unsigned int, unsigned int)", referenced from:
      (anonymous namespace)::AArch64AsmPrinter::PrintAsmOperand(llvm::MachineInstr const*, unsigned int, unsigned int, char const*, llvm::raw_ostream&) in libLLVMAArch64CodeGen.a(AArch64AsmPrinter.cpp.o)
      (anonymous namespace)::AArch64AsmPrinter::PrintAsmMemoryOperand(llvm::MachineInstr const*, unsigned int, unsigned int, char const*, llvm::raw_ostream&) in libLLVMAArch64CodeGen.a(AArch64AsmPrinter.cpp.o)
      (anonymous namespace)::AArch64AsmPrinter::printOperand(llvm::MachineInstr const*, unsigned int, llvm::raw_ostream&) in libLLVMAArch64CodeGen.a(AArch64AsmPrinter.cpp.o)
      (anonymous namespace)::AArch64AsmPrinter::printAsmMRegister(llvm::MachineOperand const&, char, llvm::raw_ostream&) in libLLVMAArch64CodeGen.a(AArch64AsmPrinter.cpp.o)
  "llvm::AArch64InstPrinter::AArch64InstPrinter(llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&)", referenced from:
      createAArch64MCInstPrinter(llvm::Triple const&, unsigned int, llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&) in libLLVMAArch64Desc.a(AArch64MCTargetDesc.cpp.o)
  "llvm::DecodeINSERTPSMask(unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeINSERTQIMask(llvm::MVT, int, int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeMOVSHDUPMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeMOVSLDUPMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVPERMILPMask(llvm::MVT, llvm::ArrayRef<unsigned long long>, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::WriteBitcodeToFile(llvm::Module const&, llvm::raw_ostream&, bool, llvm::ModuleSummaryIndex const*, bool, std::__1::array<unsigned int, 5ul>*)", referenced from:
      _LLVMExtWriteBitcodeWithSummaryToFile in llvm_ext.o
  "llvm::DecodeVPERMIL2PMask(llvm::MVT, unsigned int, llvm::ArrayRef<unsigned long long>, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::X86IntelInstPrinter::getRegisterName(unsigned int)", referenced from:
      (anonymous namespace)::X86AsmParser::ParseOperand() in libLLVMX86AsmParser.a(X86AsmParser.cpp.o)
  "llvm::DecodeScalarMoveMask(llvm::MVT, bool, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVPERM2X128Mask(llvm::MVT, unsigned int, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeZeroExtendMask(llvm::MVT, llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      resolveTargetShuffleInputs(llvm::SDValue, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, llvm::SelectionDAG&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeVectorBroadcast(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::DecodeZeroMoveLowMask(llvm::MVT, llvm::SmallVectorImpl<int>&)", referenced from:
      getTargetShuffleMask(llvm::SDNode*, llvm::MVT, bool, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SmallVectorImpl<int>&, bool&) in libLLVMX86CodeGen.a(X86ISelLowering.cpp.o)
  "llvm::AArch64AppleInstPrinter::AArch64AppleInstPrinter(llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&)", referenced from:
      createAArch64MCInstPrinter(llvm::Triple const&, unsigned int, llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&) in libLLVMAArch64Desc.a(AArch64MCTargetDesc.cpp.o)
  "llvm::DebugLoc::get(unsigned int, unsigned int, llvm::MDNode const*, llvm::MDNode const*, bool)", referenced from:
      _LLVMExtSetCurrentDebugLocation in llvm_ext.o
  "llvm::DIBuilder::createFile(llvm::StringRef, llvm::StringRef, llvm::Optional<llvm::DIFile::ChecksumInfo<llvm::StringRef> >, llvm::Optional<llvm::StringRef>)", referenced from:
      _LLVMExtDIBuilderCreateFile in llvm_ext.o
      _LLVMExtDIBuilderCreateCompileUnit in llvm_ext.o
  "llvm::DIBuilder::createFunction(llvm::DIScope*, llvm::StringRef, llvm::StringRef, llvm::DIFile*, unsigned int, llvm::DISubroutineType*, unsigned int, llvm::DINode::DIFlags, llvm::DISubprogram::DISPFlags, llvm::MDTupleTypedArrayWrapper<llvm::DITemplateParameter>, llvm::DISubprogram*, llvm::MDTupleTypedArrayWrapper<llvm::DIType>)", referenced from:
      _LLVMExtDIBuilderCreateFunction in llvm_ext.o
  "llvm::DIBuilder::createBasicType(llvm::StringRef, unsigned long long, unsigned int, llvm::DINode::DIFlags)", referenced from:
      _LLVMExtDIBuilderCreateBasicType in llvm_ext.o
  "llvm::DIBuilder::createEnumerator(llvm::StringRef, long long, bool)", referenced from:
      _LLVMExtDIBuilderCreateEnumerator in llvm_ext.o
  "llvm::DIBuilder::createCompileUnit(unsigned int, llvm::DIFile*, llvm::StringRef, bool, llvm::StringRef, unsigned int, llvm::StringRef, llvm::DICompileUnit::DebugEmissionKind, unsigned long long, bool, bool, llvm::DICompileUnit::DebugNameTableKind, bool)", referenced from:
      _LLVMExtDIBuilderCreateCompileUnit in llvm_ext.o
  "llvm::DIBuilder::createEnumerationType(llvm::DIScope*, llvm::StringRef, llvm::DIFile*, unsigned int, unsigned long long, unsigned int, llvm::MDTupleTypedArrayWrapper<llvm::DINode>, llvm::DIType*, llvm::StringRef, bool)", referenced from:
      _LLVMExtDIBuilderCreateEnumerationType in llvm_ext.o
  "llvm::DIBuilder::DIBuilder(llvm::Module&, bool, llvm::DICompileUnit*)", referenced from:
      _LLVMExtNewDIBuilder in llvm_ext.o
  "llvm::CallBase::hasFnAttrOnCalledFunction(llvm::Attribute::AttrKind) const", referenced from:
      bool llvm::CallBase::hasFnAttrImpl<llvm::Attribute::AttrKind>(llvm::Attribute::AttrKind) const in llvm_ext.o
  "vtable for llvm::X86ATTInstPrinter", referenced from:
      createX86MCInstPrinter(llvm::Triple const&, unsigned int, llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&) in libLLVMX86Desc.a(X86MCTargetDesc.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for llvm::X86IntelInstPrinter", referenced from:
      createX86MCInstPrinter(llvm::Triple const&, unsigned int, llvm::MCAsmInfo const&, llvm::MCInstrInfo const&, llvm::MCRegisterInfo const&) in libLLVMX86Desc.a(X86MCTargetDesc.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with code: 1: `cc "${@}" -o /Users/iambudi/Applications/crystalline/bin/crystalline  -rdynamic -L/usr/local/Cellar/crystal/0.35.1_1/embedded/lib -L/usr/local/lib -L/usr/local/Cellar/libyaml/0.2.5/lib -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` /usr/local/Cellar/crystal/0.35.1_1/src/llvm/ext/llvm_ext.o `"/usr/local/opt/llvm/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre -lgc -lpthread /usr/local/Cellar/crystal/0.35.1_1/src/ext/libcrystal.a -L/usr/local/Cellar/libevent/2.1.12/lib -levent_pthreads -levent -L/usr/local/Cellar/libevent/2.1.12/lib -levent -liconv -ldl`

SIGSEGV on freebsd 13.1-release

Hey,

When attempting to use crystalline it gets killed pretty quickly after being loaded by vim.

(lldb) target create "crystalline" --core "crystalline.core"
Core file '/home/llua/src/exercism/crystal/armstrong-numbers/crystalline.core' (x86_64) was loaded.
(lldb) bt
* thread #1, name = 'GC-marker-2', stop reason = signal SIGSEGV
  * frame #0: 0x0000000807e6b537 libgc-threaded.so.1`GC_mark_from + 823
    frame #1: 0x0000000807e6bcda libgc-threaded.so.1`___lldb_unnamed_symbol830 + 426
    frame #2: 0x0000000807e6bb06 libgc-threaded.so.1`GC_help_marker + 118
    frame #3: 0x0000000807e744ed libgc-threaded.so.1`___lldb_unnamed_symbol862 + 317
    frame #4: 0x0000000807ecb83a libthr.so.3`___lldb_unnamed_symbol556 + 314

Using gui

0x0000000807e6b537 โ”‚โ—†movq     0x10(%rax), %rbx 

in libgc-threaded.so.1`GC_mark_from seems to be the point at which causes it.

i was using vim-lsp with vim 9.0.1366

if executable('crystalline')
  au User lsp_setup call lsp#register_server({
      \ 'name': 'crystalline',
      \ 'cmd': {server_info->['crystalline','--stdio']},
      \ 'allowlist': ['crystal'],
      \ })
endif

along with

  • asyncomplete-lsp.vim
  • asyncomplete.vim
  • vim-crystal

Memory usage

First of all, thank you for this project. It really helps in day to day crystalling :-)

I however experience very high RAM usage of the crystalline binary.
Using vs code + crystal extension, using crystalline instead of scry.
I have two projects opened, each one very small (< 5k lines of my code, around 34k lines of code including everything in lib/).
Every day, the memory usage is above 3 GB. Currently it's 6.9 GB RES.

Isn't it a little too much? Can be something done about it? Can I do something to help?

I experience this currently with downloaded binary from release v0.3.0 for linux, even though I've used custom builds in the past with the same issue.

Autocomplete does not work when using symlinked dependencies

It seems like crystalline ignores/can't read a shards' contents if they are symlinked to some directory.

Example file tree:

- shard.yml
- src/...
- lib/
  - dep -> ~/dep

If dep is installed normally, crystalline works fine:

working

However, dep is symlinked to ~/dep, and crystalline is confused:
broken

The use case is this: I am developing a shard, while simultaneously developing an application that uses the shard. Therefore I do not want to constantly copy files between the two projects, but rather symlink my shard to the applications' lib folder.

Memory address errors on linux x64

Hi, I am using the crystal-language extension as mentioned in the README and set the path to the prebuilt crystalline version that I downloaded from the releases.
Once I start VSCode and hover something, it crashes:

[Info  - 7:31:25 PM] Crystalline LSP server is ready.
Invalid memory access (signal 11) at address 0x0
[0xe755e6] ???
Invalid memory access (signal 11) at address 0x7f5bf8b6d380
[0xd8f6f2] ???
[0x1fab153] ???
[Info  - 7:31:26 PM] Connection to server got closed. Server will restart.
[Error - 7:31:26 PM] Request textDocument/hover failed.
Error: Connection got disposed.
	at Object.dispose (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/main.js:904:25)
	at Object.dispose (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-languageclient/lib/client.js:74:35)
	at LanguageClient.handleConnectionClosed (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-languageclient/lib/client.js:2309:42)
	at LanguageClient.handleConnectionClosed (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-languageclient/lib/main.js:155:15)
	at closeHandler (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-languageclient/lib/client.js:2296:18)
	at CallbackList.invoke (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/events.js:62:39)
	at Emitter.fire (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/events.js:121:36)
	at closeHandler (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/main.js:240:26)
	at CallbackList.invoke (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/events.js:62:39)
	at Emitter.fire (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/events.js:121:36)
	at StreamMessageReader.fireClose (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/messageReader.js:111:27)
	at Socket.<anonymous> (/home/jens/.vscode/extensions/crystal-lang-tools.crystal-lang-0.6.2/node_modules/vscode-jsonrpc/lib/messageReader.js:151:46)
	at Socket.emit (events.js:228:7)
	at Pipe.<anonymous> (net.js:664:12)
[Info  - 7:31:26 PM] Crystalline LSP server is ready

I am using Fedora Linux 32 (x86_64) with Crystal 0.35.1 and VSCode 1.50.1, the Crystal Language extension version is 0.6.2

Build on Mac M1

I cannot manage to build crystalline master (ff6a712) on arm64 for LLVM 15 using Homebrew and Crystal from asdf.

I tried the following:

shards build crystalline --release --no-debug --progress -Dpreview_mt

which returns an error;

Dependencies are satisfied
Building: crystalline
Error target crystalline failed to compile:
Undefined symbols for architecture arm64:
  "llvm::EnableABIBreakingChecks", referenced from:
      llvm::VerifyEnableABIBreakingChecks in llvm_ext.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with exit status 1: cc "${@}" -o /Users/josua/p/crystalline/bin/crystalline  -rdynamic -L/Users/josua/.asdf/installs/crystal/1.8.1/embedded/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -lyaml /Users/josua/.asdf/installs/crystal/1.8.1/src/llvm/ext/llvm_ext.o `"/opt/homebrew/Cellar/llvm@15/15.0.7/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre2-8 -lgc -L/opt/homebrew/Cellar/libevent/2.1.12/lib -levent_pthreads -levent -L/opt/homebrew/Cellar/libevent/2.1.12/lib -levent -liconv

Unable to build on windows

f:\programming\source\repos\git\crystal_repos\crystalline>shards build --release
Dependencies are satisfied
Building: crystalline
LINK : warning LNK4044: unrecognized option '/Lf:/msys64/mingw64/lib'; ignored
LINK : warning LNK4044: unrecognized option '/lLLVM-16'; ignored
LINK : fatal error LNK1181: cannot open input file 'F:\windows\scoop\apps\crystal\current\src\llvm\ext\llvm_ext.obj'
Error target crystalline failed to compile:
Error: execution of command failed with exit status 2: F:\windows\visual_studio\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64\cl.exe /nologo _main.obj /Fef:\programming\source\repos\git\crystal_repos\crystalline\bin\crystalline.exe /link /LIBPATH:F:\windows\visual_studio\VC\Too
ls\MSVC\14.35.32215\atlmfc\lib\x64 /LIBPATH:F:\windows\visual_studio\VC\Tools\MSVC\14.35.32215\lib\x64 "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64" /DEBUG:FULL /PDBALTPA
TH:%_PDB% /INCREMENTAL:NO /STACK:0x800000 /LIBPATH:F:\windows\scoop\apps\crystal\current\lib F:\windows\scoop\apps\crystal\current\src\llvm/ext/llvm_ext.obj -Lf:/msys64/mingw64/lib -lLLVM-16 /ENTRY:wmainCRTStartup F:\windows\scoop\apps\crystal\current\lib\yaml.lib F:\window
s\scoop\apps\crystal\current\lib\pcre2-8.lib F:\windows\scoop\apps\crystal\current\lib\gc.lib F:\windows\visual_studio\VC\Tools\MSVC\14.35.32215\lib\x64\libcmt.lib F:\windows\scoop\apps\crystal\current\lib\iconv.lib "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\u
m\x64\advapi32.lib" F:\windows\visual_studio\VC\Tools\MSVC\14.35.32215\lib\x64\libvcruntime.lib "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64\shell32.lib" "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64\ole32.lib" "C:\Program Files (x86)\Wi
ndows Kits\10\Lib\10.0.22000.0\um\x64\WS2_32.lib" "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64\kernel32.lib" F:\windows\visual_studio\VC\Tools\MSVC\14.35.32215\lib\x64\legacy_stdio_definitions.lib "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\u
m\x64\DbgHelp.lib" "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64\libucrt.lib"

Infinite recursion on Crystal master when running on its own code

This is certainly an interesting bug...

Basically, given:

  • A Crystal compiler built from master
  • Crystalline running on its own source code

Crystalline will segfault due to infinite recursion. Here's what I've gathered so far:

  • A bisect seems to point to this PR being the start of the breakage.
  • The infinite recursion occurs around when the compiler is analyzing src/compiler/crystal/syntax/parser.cr, line 4484, where and MainVisitor.type_assign is being called on the same node infinitely.

Static build works but dynamic build doesn't

Hey! I have both crystal and shards installed in /usr/bin. I compiled them from source.

[/tmp/cr] $ crystal -v
Crystal 1.10.0 [9c011d77d] (2023-10-09)

LLVM: 15.0.7
Default target: x86_64-unknown-linux-gnu

[/tmp/cr] $ shards --version
Shards 0.17.3 [4bf845f] (2023-07-23)

I tried to compile crystalline from source to, commit e1dd820.
I managed to build it by using the following instructions:

git clone https://github.com/elbywan/crystalline
cd crystalline
shards install
mkdir bin
CRYSTAL_PATH=/usr/lib/crystal/src:lib shards build crystalline \
      --no-debug --progress --stats --production --release \
      -Dpreview_mt --ignore-crystal-version

I set the absolute path in the VS Code extension v0.8.4: /home/user/Clones/crystalline/bin/crystalline

image

I receive the following in the PROBLEMS tab and no LSP feature works.
I am using Linux:

[/tmp/cr] $ uname -a
Linux catalin 6.5.5-258.current #1 SMP PREEMPT_DYNAMIC 0 x86_64 GNU/Linux

[/tmp/cr] $ gcc --version
gcc (Solus) 12.3.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[22:32:28]
[/tmp/cr] $ clang --version
clang version 15.0.7
Target: x86_64-solus-linux
Thread model: posix
InstalledDir: /usr/bin

If you have any ideas on how to make it work let me know.

Edit 1: I used the barebones crystal executable project for testing.
I never got the dynamic build to ever run on my machine.

Edit 2: I can run the code without problems.

[/tmp/cr] $ shards run
Dependencies are satisfied
Building: cr
Executing: cr 

Edit 3: the executable from GitHub releases is statically built and it's built against musl. I am using libc.

Crystalline Fails to Run on Apple M2 Max due to Hardcoded Path and Architecture Mismatch for libyaml

Title: Crystalline Fails to Run on Apple M2 Max due to Hardcoded Path and Architecture Mismatch for libyaml

Body:

Hello,

I am running into an issue where Crystalline fails to execute due to a hardcoded path and architecture mismatch for libyaml-0.2.dylib on my Apple M2 Max MacBook Pro.

Environment:

  • Device: MacBook Pro 14" (M2 Max)
  • OS: macOS Ventura (13.4.1)
  • Architecture: Apple M2 Max (ARM64)
  • Crystal version: 1.8.2
  • Installation method: Downloaded the latest binary from the Crystalline GitHub releases page and installed it using the provided instructions.

Steps to reproduce:

  1. Download and install Crystalline using the provided instructions.
  2. Run crystalline in the terminal.

Expected Behavior:

Crystalline starts without issues.

Actual Behavior:

Crystalline fails to start and outputs the following error message:

dyld[9519]: Library not loaded: /opt/homebrew/Cellar/libyaml/0.2.5/lib/libyaml-0.2.dylib
Referenced from: <27D3AB98-2C98-3AA6-A598-A3E873DC8D20> /opt/homebrew/bin/crystalline
Reason: tried: '/opt/homebrew/Cellar/libyaml/0.2.5/lib/libyaml-0.2.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/Cellar/libyaml/0.2.5/lib/libyaml-0.2.dylib' (no such file), '/opt/homebrew/Cellar/libyaml/0.2.5/lib/libyaml-0.2.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/libyaml-0.2.dylib' (no such file), '/usr/lib/libyaml-0.2.dylib' (no such file, not in dyld cache)
fish: Job 1, 'crystalline' terminated by signal SIGABRT (Abort)

It appears that Crystalline is looking for libyaml-0.2.dylib at /usr/local/opt/libyaml/lib/libyaml-0.2.dylib, but on my system, the library is located at /opt/homebrew/Cellar/libyaml/0.2.5/lib/libyaml-0.2.dylib. Furthermore, there seems to be an architecture mismatch issue as the system is arm64 but Crystalline requires x86_64.

Any help or guidance on this issue would be appreciated, especially in regard to getting Crystalline to run on Apple's ARM-based M series chips.

Charlon

undefined reference to `LLVMExtDIBuilder*'

I was trying to build this and i keep getting this error undefined reference to 'LLVMExtDIBuilderGetOrCreateTypeArray'
(Cannot access the shell which i ran this on because i am using GitHub actions)
I am using llvm15-dev i also had a similar issue on another crystal related thing which i fixed by installing llvm16 but it seems like crystalline doesn't support llvm16
Here is the full log:

Run pwd
/home/runner/work/Crystalline-arm64-builds/Crystalline-arm64-builds
Cloning into 'crystalline'...
Resolving dependencies
Fetching https://github.com/elbywan/crystal-lsp.git
Fetching https://github.com/hugopl/version_from_shard.git
Fetching https://github.com/spider-gazelle/priority-queue.git
Fetching https://github.com/samueleaton/sentry.git
Fetching https://github.com/spider-gazelle/bisect.git
Installing lsp (0.1.2)
Installing version_from_shard (1.2.5)
Installing bisect (1.2.1)
Installing priority-queue (1.0.1)
Installing sentry (0.3.2 at e448ce8)
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#emit_fun_debug_metadata<LLVM::Function, String, Crystal::Location>:Array(Crystal::CodeGenVisitor::FunMetadata)':
main_module:(.text+0x4af33c): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4af380): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4af3a8): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4af3c8): undefined reference to `LLVMExtDIBuilderCreateSubroutineType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4af404): undefined reference to `LLVMExtDIBuilderCreateFunction'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#di_builder<LLVM::Module>:LLVM::DIBuilder':
main_module:(.text+0x4af728): undefined reference to `LLVMExtNewDIBuilder'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4af7ac): undefined reference to `LLVMExtDIBuilderCreateCompileUnit'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#get_current_debug_scope<Crystal::Location>:(LibLLVM::MetadataRef | Nil)':
main_module:(.text+0x4b0f24): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4b10d4): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4b1258): undefined reference to `LLVMExtDIBuilderCreateLexicalBlock'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#get_debug_type<Crystal::Type+, Crystal::Type+>:(LibLLVM::MetadataRef | Nil)':
main_module:(.text+0x4c76b4): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::SymbolType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4c8858): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::FloatType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4c89b0): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::BoolType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4c8b04): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::EnumType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4c8c8c): undefined reference to `LLVMExtDIBuilderGetOrCreateArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4c8ce4): undefined reference to `LLVMExtDIBuilderCreateEnumerationType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4c8d74): undefined reference to `LLVMExtDIBuilderCreateEnumerator'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#get_debug_type<Crystal::IntegerType>:Pointer(Void)':
main_module:(.text+0x4c9258): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::PointerInstanceType, Crystal::Type+>:(LibLLVM::MetadataRef | Nil)':
main_module:(.text+0x4c9b34): undefined reference to `LLVMExtDIBuilderCreatePointerType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::StaticArrayInstanceType, Crystal::Type+>:(LibLLVM::MetadataRef | Nil)':
main_module:(.text+0x4c9d84): undefined reference to `LLVMExtDIBuilderGetOrCreateArraySubrange'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4c9ea4): undefined reference to `LLVMExtDIBuilderGetOrCreateArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4c9ebc): undefined reference to `LLVMExtDIBuilderCreateArrayType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::TupleInstanceType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4ca054): undefined reference to `LLVMExtDIBuilderCreateReplaceableCompositeType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ca108): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ca304): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ca330): undefined reference to `LLVMExtDIBuilderCreateStructType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ca418): undefined reference to `LLVMExtDIBuilderCreatePointerType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ca438): undefined reference to `LLVMExtDIBuilderReplaceTemporary'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::NamedTupleInstanceType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4ca9c0): undefined reference to `LLVMExtDIBuilderCreateReplaceableCompositeType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4caa64): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cac70): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cac9c): undefined reference to `LLVMExtDIBuilderCreateStructType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cad84): undefined reference to `LLVMExtDIBuilderCreatePointerType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cada4): undefined reference to `LLVMExtDIBuilderReplaceTemporary'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<(Crystal::GenericClassInstanceType+ | Crystal::GenericClassType+ | Crystal::GenericModuleInstanceType | Crystal::GenericModuleType | Crystal::NonGenericClassType | Crystal::NonGenericModuleType+ | Crystal::VirtualType), Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4cb0fc): undefined reference to `LLVMExtDIBuilderCreateReplaceableCompositeType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb1d0): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb22c): undefined reference to `LLVMExtDIBuilderCreateUnionType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb270): undefined reference to `LLVMExtDIBuilderCreateStructType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb53c): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb76c): undefined reference to `LLVMExtDIBuilderCreatePointerType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cb78c): undefined reference to `LLVMExtDIBuilderReplaceTemporary'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<Crystal::MixedUnionType, Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4cb994): undefined reference to `LLVMExtDIBuilderCreateReplaceableCompositeType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cba50): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbc5c): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbc88): undefined reference to `LLVMExtDIBuilderCreateUnionType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbd10): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbd58): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbd9c): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbdc8): undefined reference to `LLVMExtDIBuilderCreateStructType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cbde8): undefined reference to `LLVMExtDIBuilderReplaceTemporary'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#create_debug_type<(Crystal::NilableReferenceUnionType | Crystal::ReferenceUnionType), Crystal::Type+>:Pointer(Void)':
main_module:(.text+0x4cc9c0): undefined reference to `LLVMExtDIBuilderCreateReplaceableCompositeType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ccc8c): undefined reference to `LLVMExtDIBuilderCreateMemberType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ccdcc): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ccdf8): undefined reference to `LLVMExtDIBuilderCreateUnionType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cce18): undefined reference to `LLVMExtDIBuilderReplaceTemporary'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#emit_fun_debug_metadata:debug_types:is_optimized<LLVM::Function, String, Crystal::Location, Array(LibLLVM::MetadataRef)+, Bool>:Array(Crystal::CodeGenVisitor::FunMetadata)':
main_module:(.text+0x4cd178): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cd1bc): undefined reference to `LLVMExtDIBuilderCreateBasicType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cd1e4): undefined reference to `LLVMExtDIBuilderGetOrCreateTypeArray'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cd204): undefined reference to `LLVMExtDIBuilderCreateSubroutineType'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cd244): undefined reference to `LLVMExtDIBuilderCreateFunction'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#declare_variable<String, Crystal::Type+, LLVM::Value, Crystal::Location, LLVM::BasicBlock>:Bool':
main_module:(.text+0x4cebdc): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4cecac): undefined reference to `LLVMExtDIBuilderCreateAutoVariable'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ceccc): undefined reference to `LLVMExtDIBuilderCreateExpression'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ced80): undefined reference to `LLVMExtDIBuilderInsertDeclareAtEnd'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#declare_variable<String, Crystal::Type+, LLVM::Value, (Crystal::Location | Nil), LLVM::BasicBlock>:Bool':
main_module:(.text+0x4ec898): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ec968): undefined reference to `LLVMExtDIBuilderCreateAutoVariable'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4ec988): undefined reference to `LLVMExtDIBuilderCreateExpression'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4eca3c): undefined reference to `LLVMExtDIBuilderInsertDeclareAtEnd'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#declare_debug_for_function_argument<String, Crystal::Type+, Int32, LLVM::Value, (Crystal::Location | Nil)>:LLVM::Value':
main_module:(.text+0x4f99cc): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4f9a44): undefined reference to `LLVMExtDIBuilderCreateParameterVariable'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4f9a64): undefined reference to `LLVMExtDIBuilderCreateExpression'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x4f9b5c): undefined reference to `LLVMExtDIBuilderInsertDeclareAtEnd'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: _main.o: in function `*Crystal::CodeGenVisitor#declare_var<Crystal::Var+>:Crystal::CodeGenVisitor::LLVMVar':
main_module:(.text+0x520fcc): undefined reference to `LLVMExtDIBuilderCreateFile'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x5210a4): undefined reference to `LLVMExtDIBuilderCreateAutoVariable'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x5210c4): undefined reference to `LLVMExtDIBuilderCreateExpression'
/usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: main_module:(.text+0x52119c): undefined reference to `LLVMExtDIBuilderInsertDeclareAtEnd'
collect2: error: ld returned 1 exit status
Error: execution of command failed with exit status 1: cc "${@}" -o /home/runner/work/Crystalline-arm64-builds/Crystalline-arm64-builds/crystalline/bin/crystalline  -rdynamic -L/usr/bin/../lib/crystal -lyaml /usr/lib/crystal/core/llvm/ext/llvm_ext.o `"/usr/bin/llvm15-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre2-8 -lgc -levent_pthreads -levent -levent
[1/13] Parse                             
[1/13] Parse                             
[2/13] Semantic (top level)              
[2/13] Semantic (top level)              
[3/13] Semantic (new)                    
[3/13] Semantic (new)                    
[4/13] Semantic (type declarations)      
[4/13] Semantic (type declarations)      
[5/13] Semantic (abstract def check)     
[5/13] Semantic (abstract def check)     
[6/13] Semantic (restrictions augmenter) 
[6/13] Semantic (restrictions augmenter) 
[7/13] Semantic (ivars initializers)     
[7/13] Semantic (ivars initializers)     
[8/13] Semantic (cvars initializers)     
[8/13] Semantic (cvars initializers)     
[9/13] Semantic (main)                   
[9/13] Semantic (main)                   
[10/13] Semantic (cleanup)                
[10/13] Semantic (cleanup)                
[11/13] Semantic (recursive struct check) 
[11/13] Semantic (recursive struct check) 
[12/13] Codegen (crystal)                 
[12/13] Codegen (crystal)                 
[13/13] Codegen (bc+obj)                  
[13/13] [0/1] Codegen (bc+obj)                  
[13/13] [0/1] Codegen (bc+obj)                  
[14/13] Codegen (linking)                 
Error: Process completed with exit code 1.

Missing linking file could be handled automatically by Crystalline's build process.

For understandable reasons, Crystal doesn't ship linking files out with the Crystal repo, since they are platform specific. However, because of that the Crystalline build fails unless an extra manual step is taken, and this manual step is not easily discovered without notable coding expertise or significant searching.

I think it would be appropriate for Crystalline to detect the existence of llvm_ext.o and build it as part of the Crystalline build process if it is missing to alleviate this.

I tried to use Crystalline (language server) with VSCode on macOS : Issue with the location of llvm@14/14.0.6/lib/libLLVM.dylib

I tried to use Crystalline (language server) with VSCode on macOS, got :

dyld[3268]: Library not loaded: /usr/local/opt/llvm@14/lib/libLLVM.dylib
  Referenced from: <DF523EFC-CF38-3988-93E4-C884DD15CA5F> /Users/sergehulne/crystalline
  Reason: tried: '/usr/local/opt/llvm@14/lib/libLLVM.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/llvm@14/lib/libLLVM.dylib' (no such file), '/usr/local/opt/llvm@14/lib/libLLVM.dylib' (no such file), '/usr/local/lib/libLLVM.dylib' (no such file), '/usr/lib/libLLVM.dylib' (no such file, not in dyld cache)
[Info  - 11:52:33] Connection to server got closed. Server will restart.

brew list llvm@14 | grep "ibLLVM.dylib" yields :

brew list llvm@14 | grep "ibLLVM.dylib"
/opt/homebrew/Cellar/llvm@14/14.0.6/lib/libLLVM.dylib

Formatter runs forever

When I enable this in vscode with format on save enabled the formatter runs forever with 100% cpu. Formatting is working fine without the language server, so could you add an option to disable it in the language server?

code --version
1.52.1
ea3859d4ba2f3e577a159bc91e3074c5d85c0523
x64

macos 11.1

crystalline 0.2

Linker error on ArchLinux since 0.7.0

Hi,

When trying to compile crystalline on Archlinux it errors out with a linker error:

Dependencies are satisfied
Building: crystalline
Error target crystalline failed to compile:     
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x2b): undefined reference to `llvm_ext.cc.c4a0b00d'
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x34): undefined reference to `llvm_ext.cc.c4a0b00d'
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x4f): undefined reference to `llvm_ext.cc.c4a0b00d'
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x56): undefined reference to `llvm_ext.cc.c4a0b00d'
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x5e): undefined reference to `llvm_ext.cc.c4a0b00d'
/usr/bin/ld: /tmp/cchyRA6H.ltrans0.ltrans.o:(.debug_info+0x79): more undefined references to `llvm_ext.cc.c4a0b00d' follow
collect2: error: ld returned 1 exit status
Error: execution of command failed with exit status 1: cc "${@}" -o /home/hugo/src/pet/aur/crystalline-package/src/crystalline-0.10.0/bin/crystalline  -rdynamic -L/usr/bin/../lib/crystal -lyaml  /usr/lib/crystal/llvm/ext/llvm_ext.o `"/usr/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre2-8 -lm -lgc -lpthread -levent_pthreads -levent  -levent  -lrt -lpthread -ldl

Looking at the information provided by crystal-lang/crystal#13563, these symbols are on llvm_ext.cc on crystal sources, so I believe they must be included in Crystalline and compiled/linked in order to have it compile on Archlinux and possible other distributions.

Tested with LLVM15

Hover provider returning "?" for any variable

Hi,
first of all, gratz for the great work!

That being said, I have a problem with the hover provider, I am probably doing something wrong from my part, but I cannot really understand what.
For any variable, when I hover on it, I always get a "?" as an answer, like the following one:
image
Is it something normal or is something I can fix?

Error: cannot open ./crystalline/bin/crystalline during install

Hello,

Thanks for your hard work.

I try to install Crystalline on Ubuntu 18.04 (llvm 11) and I have this error:

$ crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug --progress  -Dpreview_mt
/usr/bin/ldย : ne peut ouvrir le fichier de sortie /home/nico/tmp/crystalline/bin/crystallineย : Aucun fichier ou dossier de ce type
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc "${@}" -o /home/nico/tmp/crystalline/bin/crystalline  -rdynamic -L/usr/bin/../lib/crystal/lib -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` /usr/share/crystal/src/llvm/ext/llvm_ext.o `"/usr/bin/llvm-config-11" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre -lm -lgc -lpthread /usr/share/crystal/src/ext/libcrystal.a -levent_pthreads -levent -levent -lrt -ldl`

My full install is:

sudo apt-get update
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
# whereis llvm-config-11 (v11 for me), when located:
export LLVM_CONFIG=/usr/bin/llvm-config-11
crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug --progress  -Dpreview_mt
crystal version
Crystal 0.35.1 [5999ae29b] (2020-06-19)

LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu

An idea?

High CPU usage

I'm running crystalline within a fairly large project. The CPU usage is pending between 20% and 60% with the codebase completely idle. Upon a save it can reach more than 200% (Using top on OSX to read these values)

Compilation error "Undefined symbols" in llvm including AtomicCmpXchgInst and buildModulesSummaryIndex

For what it's worth, with latest everything (Crystal 0.35.1, macos 11.0.1, LLVM 11.0.0), crystalline seems to fail to build with this error:

$ env LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug --progress -Dpreview_mt
Undefined symbols for architecture x86_64:      
  "llvm::AtomicCmpXchgInst::AtomicCmpXchgInst(llvm::Value*, llvm::Value*, llvm::Value*, llvm::AtomicOrdering, llvm::AtomicOrdering, unsigned char, llvm::Instruction*)", referenced from:
      llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateAtomicCmpXchg(llvm::Value*, llvm::Value*, llvm::Value*, llvm::AtomicOrdering, llvm::AtomicOrdering, unsigned char) in llvm_ext.o
  "llvm::buildModuleSummaryIndex(llvm::Module const&, std::__1::function<llvm::BlockFrequencyInfo* (llvm::Function const&)>, llvm::ProfileSummaryInfo*)", referenced from:
      _LLVMExtWriteBitcodeWithSummaryToFile in llvm_ext.o
     (maybe you meant: llvm::buildModuleSummaryIndex(llvm::Module const&, std::__1::function<llvm::BlockFrequencyInfo* (llvm::Function const&)>, llvm::ProfileSummaryInfo*, std::__1::function<llvm::StackSafetyInfo const* (llvm::Function const&)>))
  "llvm::DIBuilder::createCompileUnit(unsigned int, llvm::DIFile*, llvm::StringRef, bool, llvm::StringRef, unsigned int, llvm::StringRef, llvm::DICompileUnit::DebugEmissionKind, unsigned long long, bool, bool, llvm::DICompileUnit::DebugNameTableKind, bool)", referenced from:
      _LLVMExtDIBuilderCreateCompileUnit in llvm_ext.o
     (maybe you meant: llvm::DIBuilder::createCompileUnit(unsigned int, llvm::DIFile*, llvm::StringRef, bool, llvm::StringRef, unsigned int, llvm::StringRef, llvm::DICompileUnit::DebugEmissionKind, unsigned long long, bool, bool, llvm::DICompileUnit::DebugNameTableKind, bool, llvm::StringRef, llvm::StringRef))
ld: symbol(s) not found for architecture x86_64
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with code: 1: `/usr/local/opt/llvm/bin/clang "${@}" -o /Users/liteyear/Downloads/crystalline/bin/crystalline  -rdynamic -L/usr/local/Cellar/crystal/0.35.1_1/embedded/lib -L/usr/local/lib -L/usr/local/Cellar/libyaml/0.2.5/lib -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` /usr/local/Cellar/crystal/0.35.1_1/src/llvm/ext/llvm_ext.o `"/usr/local/opt/llvm/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre -lgc -lpthread /usr/local/Cellar/crystal/0.35.1_1/src/ext/libcrystal.a -L/usr/local/Cellar/libevent/2.1.12/lib -levent_pthreads -levent -L/usr/local/Cellar/libevent/2.1.12/lib -levent -liconv -ldl`

Seems to be an LLVM change, but Homebrew doesn't have LLVM@10, so not sure if it's worth rolling back to another version?

code autocomplete is tool slow

code autocomplete is tool slow , somtetimes it need >2s for generate suggestions. Most time consumption is greater than 1 second.

Crystalline is ignoring "hierarchicalDocumentSymbolSupport" on "documentSymbol" client capabilities.

Hi,

Crystalline seems far better than first time I checked out, before first release, so I'm trying to use it on my editor and probably let it be the default LS for Crystal. However I found a minor issue that in my understanding seems like a wrong implementation of the LSP spec:

If the client capabilities for documentSymbol is set as:

    "documentSymbol": {
        "dynamicRegistration": false,
        "symbolKind": {
            "valueSet": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]
        },
        "hierarchicalDocumentSymbolSupport": false
    }

A documentSymbol request should create a response with an array of SymbolInformation when hierarchicalDocumentSymbolSupport is set to false on client capabilities, but Crystalline is always sending an array of DocumentSymbol.

How to reproduce

  1. Compile master branch of Tijolo
  2. start it with tijolo --debug in some terminal.
  3. Configure it to use crystallise (:hamburger: menu -> preferences, replace crystal = "scry" by `crystal = "crystalline"
  4. Open a crystal file, hit Ctrp + P then type . (dot space).
  5. See the LSP communication on terminal, log file at /tmp or pressing Alt + 2

Compilation of Crystalline failed on Mac M1

command issued:

shards build crystalline --release --no-debug --progress -Dpreview_mt

Resulting error message

Resolving dependencies
Fetching https://github.com/hugopl/version_from_shard.git
Fetching https://github.com/spider-gazelle/priority-queue.git
Fetching https://github.com/samueleaton/sentry.git
Fetching https://github.com/spider-gazelle/bisect.git
Installing version_from_shard (1.2.4)
Installing bisect (1.2.1)
Installing priority-queue (1.0.1)
Installing sentry (0.3.2 at cd86128)
Building: crystalline
[13/13] [0/1] Codegen (bc+obj)                  
Error target crystalline failed to compile:     
Undefined symbols for architecture arm64:
  "llvm::DIBuilder::createFunction(llvm::DIScope*, llvm::StringRef, llvm::StringRef, llvm::DIFile*, unsigned int, llvm::DISubroutineType*, unsigned int, llvm::DINode::DIFlags, llvm::DISubprogram::DISPFlags, llvm::MDTupleTypedArrayWrapper<llvm::DITemplateParameter>, llvm::DISubprogram*, llvm::MDTupleTypedArrayWrapper<llvm::DIType>, llvm::MDTupleTypedArrayWrapper<llvm::DINode>)", referenced from:
      _LLVMExtDIBuilderCreateFunction in llvm_ext.o
  "llvm::DIBuilder::createMemberType(llvm::DIScope*, llvm::StringRef, llvm::DIFile*, unsigned int, unsigned long long, unsigned int, unsigned long long, llvm::DINode::DIFlags, llvm::DIType*, llvm::MDTupleTypedArrayWrapper<llvm::DINode>)", referenced from:
      _LLVMExtDIBuilderCreateMemberType in llvm_ext.o
  "llvm::DIBuilder::createPointerType(llvm::DIType*, unsigned long long, unsigned int, llvm::Optional<unsigned int>, llvm::StringRef, llvm::MDTupleTypedArrayWrapper<llvm::DINode>)", referenced from:
      _LLVMExtDIBuilderCreatePointerType in llvm_ext.o
  "llvm::DIBuilder::createParameterVariable(llvm::DIScope*, llvm::StringRef, unsigned int, llvm::DIFile*, unsigned int, llvm::DIType*, bool, llvm::DINode::DIFlags, llvm::MDTupleTypedArrayWrapper<llvm::DINode>)", referenced from:
      _LLVMExtDIBuilderCreateParameterVariable in llvm_ext.o
  "llvm::DIBuilder::createReplaceableCompositeType(unsigned int, llvm::StringRef, llvm::DIScope*, llvm::DIFile*, unsigned int, unsigned int, unsigned long long, unsigned int, llvm::DINode::DIFlags, llvm::StringRef, llvm::MDTupleTypedArrayWrapper<llvm::DINode>)", referenced from:
      _LLVMExtDIBuilderCreateReplaceableCompositeType in llvm_ext.o
  "llvm::AttributeList::addAttributeAtIndex(llvm::LLVMContext&, unsigned int, llvm::Attribute::AttrKind) const", referenced from:
      llvm::IRBuilderBase::CreateCall(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, llvm::Twine const&, llvm::MDNode*) in llvm_ext.o
      llvm::IRBuilderBase::CreateInvoke(llvm::FunctionType*, llvm::Value*, llvm::BasicBlock*, llvm::BasicBlock*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, llvm::Twine const&) in llvm_ext.o
  "llvm::AttributeList::addAttributeAtIndex(llvm::LLVMContext&, unsigned int, llvm::StringRef, llvm::StringRef) const", referenced from:
      _LLVMExtCreateMCJITCompilerForModule in llvm_ext.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with code: 1: `cc "${@}" -o /Users/sergehulne/Documents/code/Crystal/crystalline/bin/crystalline  -rdynamic -L/opt/homebrew/Cellar/crystal/1.6.0/libexec/../../../../lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -lyaml /opt/homebrew/Cellar/crystal/1.6.0/share/crystal/src/llvm/ext/llvm_ext.o `"/opt/homebrew/opt/llvm/bin/llvm-config" --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -lpcre -lgc -L/opt/homebrew/Cellar/libevent/2.1.12/lib -levent_pthreads -levent -L/opt/homebrew/Cellar/libevent/2.1.12/lib -levent -liconv`

Incorrect info in methods

I have a file that cystalline seems to have problems with. Is there somewhere I could look in the code to help contribute?

Screen Shot 2022-09-28 at 10 26 52 PM

Screen Shot 2022-09-28 at 10 23 53 PM

How would I test whether this is a VS Code extension vs. Crystalline issue?

This is the code it has problems with:

module PostProcess
  extend self

  ORS_CHAPTER_REGEX = /ORS Chapter (?<num>[1-9]\w?\w?\w?)\b/

  def add_ors_chapter_links(text : String) : String
    return text if text.blank?

    text.gsub(ORS_CHAPTER_REGEX) do |_, match|
      full_citation = match[0]
      number = match.named_captures["num"]
      chapter_url = "/statutes/ors_chapter_#{number}"

      "<a href='#{chapter_url}'>#{full_citation}</a>"
    end
  end
end

It has this issue in all my methods, except this one, which it handles fine. If I remove the graphql annotations, it fails. (?)

@[GraphQL::Object]
class Query < GraphQL::BaseQuery
  @[GraphQL::Field(description: "Modify existing links when there's a pinpoint citation.")]
  def add_pinpoint_links(html : String) : String
    PinpointXref.add_pinpoint(html)
  end
end

[RFC] Extract LSP protocol-only code to a separate shard

Extracted from #53

I think it would be nice to extract the code that's exclusive to LSP to a separate shard. The advantages of doing that are:

  1. Clearer separation of concerns
  2. Less code in this repository, making it more accessible
  3. Avoiding duplicating code and effort (there's already another repo for this)
  4. Allowing others to use the LSP shard for other language server implementations (not only Crystal ones. For example there could be one for Mint).

One possible place for this new repo could be in elbywan. Another place could be crystal-community to encourage contributions.

[RFC] Fault-tolerant parsing

Extracted from #53

Right now autocompletion and other features (like the hierarchy tree that's shown at the top of the file) doesn't work if the source isn't valid Crystal code but it's almost valid Crystal code. These cases happen because the user is typing a new, but incomplete, expression.

Some of these cases are already handled by Crystalline. For example:

hello = 1
hello.|

Autocompletions work fine here because, I think, if the completion happens after a dot the rest of the line is cleared to allow a more successful parsing. Like this:

# No errors anymore
hello = 1
hello

In that case we could maybe transform the code to this:

hello = 1
hello.itself

Or maybe

hello = 1
hello.`the empty string`

that is, parse it to a call where the method name is empty, if the cursor happens to be right after the dot and nothing else is coming (or a newline is coming, etc.)

Here's another example:

hello = 1

if hello.|

In this case autocompletion doesn't work because the "remove everything after the dot" trick doesn't help because the code is missing an end. One idea here is to first rewrite the code to this:

hello = 1

if hello.|; end

That is, we add a ; end when appropriate to make it pass (combined with the previous fix of the "dot empty" sequence it will parse correctly.)

Some of these ideas are also expressed here: https://bugs.ruby-lang.org/issues/19013

I think this will be mostly about heuristics, finding cases that break and trying to fix them, so it's important to have tests for this to make sure we don't introduce regressions.

If it's fine with you I can start working on this. My idea is to first have a way to add the missing ends or curly braces based only on the indentation of the code. Then have a fault-tolerant parser, or a cursor-aware parser, that will produce a valid AST in case something is missing (like the first example here.)

Is this project active? I have some ideas

Hi!

First of all, thank you so much for this project!

I have some ideas of how to provide autocompletion that wouldn't take that much time, although it might not be 100% accurate. I thought about creating a separate project but maybe it's better if I contribute to this one.

But before sharing my ideas, I'd like to understand a few things:

  • Is this project active? Would it accept contributions?
  • Is there an overview of how things work now?

After that, I could share some ideas I have... if they are very different from how things are working now :-)

Thank you!

LSP server crashes if there is a syntax error

[Info  - 9:27:32 AM] Crystalline LSP server is ready.
[Error - 9:28:34 AM] syntax error in :2
Error: expecting any of these tokens: IDENT, CONST, +, -, *, /, //, %, |, &, ^, ~, !, **, <<, <, <=, ==, !=, =~, !~, >>, >, >=, <=>, ===, [], []=, []?, [, &+, &-, &*, &** (not 'EOF')
[Error - 9:28:34 AM] Request textDocument/formatting failed.
  Message: expecting any of these tokens: IDENT, CONST, +, -, *, /, //, %, |, &, ^, ~, !, **, <<, <, <=, ==, !=, =~, !~, >>, >, >=, <=>, ===, [], []=, []?, [, &+, &-, &*, &** (not 'EOF')
  Code: -32001 
raise<Crystal::SyntaxException>:NoReturn,Crystal::Parser@Crystal::Lexer#raise<String, Crystal::Token, Nil>:NoReturn,Crystal::Parser@Crystal::Lexer#raise<String, Crystal::Token>:NoReturn,Crystal::Parser#parse_atomic_method_suffix<Crystal::ASTNode+, Crystal::Location>:Crystal::ASTNode+,Crystal::Parser#parse_pow:Crystal::ASTNode+,Crystal::Parser#parse_mul_or_div:Crystal::ASTNode+,Crystal::Parser#parse_add_or_sub:Crystal::ASTNode+,Crystal::Parser#parse_shift:Crystal::ASTNode+,Crystal::Parser#parse_logical_and:Crystal::ASTNode+,Crystal::Parser#parse_logical_or:Crystal::ASTNode+,Crystal::Parser#parse_cmp:Crystal::ASTNode+,Crystal::Parser#parse_equality:Crystal::ASTNode+,Crystal::Parser#parse_and:Crystal::ASTNode+,Crystal::Parser#parse_or:Crystal::ASTNode+,Crystal::Parser#parse_question_colon:Crystal::ASTNode+,Crystal::Parser#parse_op_assign<Bool, Bool>:Crystal::ASTNode+,Crystal::Parser#parse_multi_assign:Crystal::ASTNode+,Crystal::Parser#parse_expressions_internal:Crystal::ASTNode+,Crystal::Formatter::format<String, Nil>:String,Crystalline::Controller#on_request<(LSP::CompletionRequest | LSP::DefinitionRequest | LSP::HoverRequest | LSP::InitializeRequest | LSP::RequestMessage(Array(LSP::TextEdit) | Nil)+ | LSP::RequestMessage(Nil)+ | LSP::ShowMessageRequest | LSP::SignatureHelpRequest)>:(Array(LSP::Location | LSP::LocationLink) | Array(LSP::TextEdit) | LSP::CompletionList | LSP::Hover | Nil),~procProc(Nil)@lib/crystalline/src/crystalline/lsp/server.cr:148,Fiber#run:(IO::FileDescriptor | Nil)

If you put a dot after anything literally and save it, the server will crash and won't restart until you restart VS Code.

[help?] Can someone give me a linux-arm64 build?

I just fall in love with crystal, and my low end mobile phone blow up trying to build this; if someone has a powerful enough device that is linux-arm64 i will be thankful (i know i shouldn't beg here but anyways) ๐Ÿ™๐Ÿ™๐Ÿ™

Crystalline is publishing diagnostics for Crystal internal files

Hi,

The diagnostics are being sent for files in Crystal stdlib and files under project lib directory. This could be skip to save a lot of messages exchange between client and server.

{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///usr/lib/crystal/prelude.cr","diagnostics":[]}}

Also... when a file is saved it send the diagnostics for all files too, I think the spec isn't clear about this but IMO makes more sense to send this diagnostics only for open files... anyway, better look what other LS are doing, so I'm not sure this last paragraph is really an issue.

`formatOnPaste` leads to added newline after each paste

I'm using VSCodium Version: 1.76.2, vscode-crystal-lang v0.8.4, crystalline v0.8.0 (x86_64-apple-darwin).

Whenever I paste some text, a \n is added directly after the pasted text.

foo "bar"
    ^ paste "text" here

results in

foo "text"
"bar"

As a work-around, I've disabled editor.formatOnPaste in the VSCodium settings.json:

{
    "[crystal]": {
        "editor.formatOnPaste": false
    }
}

Not an issue

I just wanted to communicate to you how much your effort inspires me and that I think you're a beautiful being for undertaking such a great task. You're awesome

support crystal 1.2.0

my crystal version is 1.2.0

git clone to my local dir, and then i run the command like this.

$ env LLVM_CONFIG=/usr/local/opt/llvm/bin/llvm-config crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug -Dpreview_mt
Showing last frame. Use --error-trace for full trace.

In /usr/local/Cellar/crystal/1.2.0/src/compiler/crystal/tools/doc/generator.cr:1:1

 1 | require "../../../../../lib/markd/src/markd"
     ^
Error: can't find file '../../../../../lib/markd/src/markd' relative to '/usr/local/Cellar/crystal/1.2.0/src/compiler/crystal/tools/doc/generator.cr'

maybe it's not support 1.2.0?

Issues with HEAD and Crystal 1.6

On 20e585d (current HEAD):

crystalline % shards 
Resolving dependencies
Fetching https://github.com/hugopl/version_from_shard.git
Fetching https://github.com/spider-gazelle/priority-queue.git
Fetching https://github.com/samueleaton/sentry.git
Fetching https://github.com/spider-gazelle/bisect.git
Installing version_from_shard (1.2.4)
Installing bisect (1.2.1)
Installing priority-queue (1.0.1)
Installing sentry (0.3.2 at cd86128)
(base) russ@hilaptop crystalline % env LLVM_CONFIG=/opt/homebrew/Cellar/llvm/15.0.1/bin/llvm-config crystal build ./src/crystalline.cr  -o ./bin/crystalline --release --no-debug -Dpreview_mt
Showing last frame. Use --error-trace for full trace.

In /opt/homebrew/Cellar/crystal/1.6.0/share/crystal/src/compiler/crystal/semantic/cover.cr:7:22

 7 | getter matches : ZeroOneOrMany(Match)
                      ^------------
Error: undefined constant ZeroOneOrMany
crystalline % 

Presumably this is something todo with Crystal 1.6 and crystal-lang/crystal#12405...

Start crystalline failed partially when used with emacs.

Hi, not use crystalline for a long time, because it not work before, i can see notification said crystalline start successful, the process is really started too.

 โ•ฐโ”€ $ ps aux |grep crystalline
zw963     571897  0.3  0.3 313408 187136 ?       Ssl  04:14   0:00 /home/zw963/Crystal/bin/crystalline --stdio

Even, i can saw breadcrumb showed correctly, but it just not working, no any crystalline support feature available.

I saw crystalline release the new version, so just try it again. but no luck, so, i start thought, maybe this is somewhat option issue, did I enable an option that crystalline does not support?

Following is error message which enable debug-on-error option.


error messages Debugger entered--Lisp error: (wrong-type-argument stringp nil) directory-file-name(nil) lsp-diagnostics--update-path(nil [0 1 0 0 0]) lsp--on-diagnostics-update-stats(#s(lsp--workspace :ewoc #s(ewoc :buffer # :pretty-printer lsp--log-entry-pp :header [[[[... #5 ... #] #4 "" #] #3 DL-LIST #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time 105 :type incoming-resp :method "initialize" :id 1 :body #) #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body (:processId 575232 :rootPath "/home/zw963/Crystal/crystal-china/translater" :clientInfo ... :rootUri "file:///home/zw963/Crystal/crystal-china/tra..." :capabilities ... :initializationOptions nil :workDoneToken "1")) #] "" #] :footer [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "$/progress" :id nil :body #) #] #3 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] [#3 [#4 [#5 ... ... #] "" #] DL-LIST #] "" #] :dll [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] #3 "" #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body ...) #] "" #] DL-LIST #] :last-node nil :hf-pp insert) :server-capabilities # :registered-server-capabilities nil :root "/home/zw963/Crystal/crystal-china/translater" :client #s(lsp--client :language-id nil :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn workspace) #) :test? #f(compiled-function () #)) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes (crystal-mode) :activation-fn nil :priority 0 :server-id crystalline :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn nil :download-in-progress? nil :buffers nil :synchronize-sections nil) :host-root nil :proc # :cmd-proc # :buffers (#) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata # :watches # :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics # :work-done-tokens #) #) lsp--on-diagnostics(#s(lsp--workspace :ewoc #s(ewoc :buffer # :pretty-printer lsp--log-entry-pp :header [[[[... #5 ... #] #4 "" #] #3 DL-LIST #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time 105 :type incoming-resp :method "initialize" :id 1 :body #) #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body (:processId 575232 :rootPath "/home/zw963/Crystal/crystal-china/translater" :clientInfo ... :rootUri "file:///home/zw963/Crystal/crystal-china/tra..." :capabilities ... :initializationOptions nil :workDoneToken "1")) #] "" #] :footer [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "$/progress" :id nil :body #) #] #3 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] [#3 [#4 [#5 ... ... #] "" #] DL-LIST #] "" #] :dll [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] #3 "" #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body ...) #] "" #] DL-LIST #] :last-node nil :hf-pp insert) :server-capabilities # :registered-server-capabilities nil :root "/home/zw963/Crystal/crystal-china/translater" :client #s(lsp--client :language-id nil :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn workspace) #) :test? #f(compiled-function () #)) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes (crystal-mode) :activation-fn nil :priority 0 :server-id crystalline :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn nil :download-in-progress? nil :buffers nil :synchronize-sections nil) :host-root nil :proc # :cmd-proc # :buffers (#) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata # :watches # :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics # :work-done-tokens #) #) lsp--on-notification(#s(lsp--workspace :ewoc #s(ewoc :buffer # :pretty-printer lsp--log-entry-pp :header [[[[... #5 ... #] #4 "" #] #3 DL-LIST #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time 105 :type incoming-resp :method "initialize" :id 1 :body #) #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body (:processId 575232 :rootPath "/home/zw963/Crystal/crystal-china/translater" :clientInfo ... :rootUri "file:///home/zw963/Crystal/crystal-china/tra..." :capabilities ... :initializationOptions nil :workDoneToken "1")) #] "" #] :footer [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "$/progress" :id nil :body #) #] #3 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] [#3 [#4 [#5 ... ... #] "" #] DL-LIST #] "" #] :dll [[[[... #5 ... #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] #3 "" #] [#3 [#4 [#5 ... ... #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body ...) #] "" #] DL-LIST #] :last-node nil :hf-pp insert) :server-capabilities # :registered-server-capabilities nil :root "/home/zw963/Crystal/crystal-china/translater" :client #s(lsp--client :language-id nil :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn workspace) #) :test? #f(compiled-function () #)) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes (crystal-mode) :activation-fn nil :priority 0 :server-id crystalline :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn nil :download-in-progress? nil :buffers nil :synchronize-sections nil) :host-root nil :proc # :cmd-proc # :buffers (#) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata # :watches # :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics # :work-done-tokens #) #) lsp--parser-on-message(# #s(lsp--workspace :ewoc #s(ewoc :buffer # :pretty-printer lsp--log-entry-pp :header [[[[... #6 ... #] #5 "" #] #4 DL-LIST #] [#4 [#5 [#6 ... ... #] #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time 105 :type incoming-resp :method "initialize" :id 1 :body #) #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body (:processId 575232 :rootPath "/home/zw963/Crystal/crystal-china/translater" :clientInfo ... :rootUri "file:///home/zw963/Crystal/crystal-china/tra..." :capabilities ... :initializationOptions nil :workDoneToken "1")) #] "" #] :footer [[[[... #6 ... #] #5 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "$/progress" :id nil :body #) #] #4 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] [#4 [#5 [#6 ... ... #] "" #] DL-LIST #] "" #] :dll [[[[... #6 ... #] #5 #s(lsp--log-entry :timestamp "04:27:12 AM" :process-time nil :type incoming-notif :method "textDocument/publishDiagnostics" :id nil :body #) #] #4 "" #] [#4 [#5 [#6 ... ... #] #s(lsp--log-entry :timestamp "04:27:11 AM" :process-time nil :type outgoing-req :method "initialize" :id 1 :body ...) #] "" #] DL-LIST #] :last-node nil :hf-pp insert) :server-capabilities # :registered-server-capabilities nil :root "/home/zw963/Crystal/crystal-china/translater" :client #s(lsp--client :language-id nil :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn workspace) #) :test? #f(compiled-function () #)) :ignore-regexps nil :ignore-messages nil :notification-handlers # :request-handlers # :response-handlers # :prefix-function nil :uri-handlers # :action-handlers # :major-modes (crystal-mode) :activation-fn nil :priority 0 :server-id crystalline :multi-root nil :initialization-options nil :semantic-tokens-faces-overrides nil :custom-capabilities nil :library-folders-fn nil :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? nil :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn nil :async-request-handlers # :download-server-fn nil :download-in-progress? nil :buffers nil :synchronize-sections nil) :host-root nil :proc # :cmd-proc # :buffers (#) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata # :watches # :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics # :work-done-tokens #)) #f(compiled-function (msg) #)(#) mapc(#f(compiled-function (msg) #) (# #)) #f(compiled-function (proc input) #)(# "Content-Length: 320\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file://\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":0,\"character\":-1},\"end\":{\"line\":0,\"character\":-1}},\"severity\":1,\"source\":\"\",\"message\":\"abstract `def Object#hash(hasher)` must be implemented by ReferenceStorage(T)\",\"relatedInformation\":[]}]}}Content-Length: 138\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"$/progress\",\"params\":{\"token\":\"workspace/compile/0\",\"value\":{\"message\":\"Completed with errors.\",\"kind\":\"end\"}}}")

It look's like those error about lsp update diagnostics status? but, i checked the README, it said, crystalline support diagnostics, right?

BTW: there should not a emacs config issue, at least, the emacs lsp for go, rust use same settings, work quite well.

My emacs lsp settings is here

thanks.

Can not find classes in Lucky project

crystalline doesn't work in Lucky projects, becuse it can't find required classes in migrations. The reason can be that the db/ directory is in the project root, not in the src/ folder.

Also, it doesn't work with macro-generated Lucky classes, like MyModel::DeleteOperation.

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.