mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
* grammars: Update several grammars with compat issues * [WIP] Add new grammar conversion tools * Wrap in a Docker script * Proper Dockerfile support * Add Javadoc grammar * Remove NPM package.json * Remove superfluous test This is now always checked by the grammars compiler * Update JSyntax grammar to new submodule * Approve Javadoc license * grammars: Remove checked-in dependencies * grammars: Add regex checks to the compiler * grammars: Point Oz to its actual submodule * grammars: Refactor compiler to group errors by repo * grammars: Cleanups to error reporting
97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
package compiler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
grammar "github.com/github/linguist/tools/grammars/proto"
|
|
"github.com/groob/plist"
|
|
"github.com/mitchellh/mapstructure"
|
|
yaml "gopkg.in/yaml.v2"
|
|
)
|
|
|
|
func looseDecoder(f reflect.Kind, t reflect.Kind, data interface{}) (interface{}, error) {
|
|
dataVal := reflect.ValueOf(data)
|
|
switch t {
|
|
case reflect.Bool:
|
|
switch f {
|
|
case reflect.Bool:
|
|
return dataVal.Bool(), nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return (int(dataVal.Float()) != 0), nil
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return (dataVal.Int() != 0), nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return (dataVal.Uint() != 0), nil
|
|
case reflect.String:
|
|
switch dataVal.String() {
|
|
case "1":
|
|
return true, nil
|
|
case "0":
|
|
return false, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func filterUnusedKeys(keys []string) (out []string) {
|
|
for _, k := range keys {
|
|
parts := strings.Split(k, ".")
|
|
field := parts[len(parts)-1]
|
|
if !KnownFields[field] {
|
|
out = append(out, k)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func ConvertProto(ext string, data []byte) (*grammar.Rule, []string, error) {
|
|
var (
|
|
raw map[string]interface{}
|
|
out grammar.Rule
|
|
err error
|
|
md mapstructure.Metadata
|
|
)
|
|
|
|
switch strings.ToLower(ext) {
|
|
case ".plist", ".tmlanguage":
|
|
err = plist.Unmarshal(data, &raw)
|
|
case ".yaml-tmlanguage":
|
|
err = yaml.Unmarshal(data, &raw)
|
|
case ".cson":
|
|
data, err = ConvertCSON(data)
|
|
if err == nil {
|
|
err = json.Unmarshal(data, &raw)
|
|
}
|
|
case ".json":
|
|
err = json.Unmarshal(data, &raw)
|
|
default:
|
|
err = fmt.Errorf("grammars: unsupported extension '%s'", ext)
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
config := mapstructure.DecoderConfig{
|
|
Result: &out,
|
|
Metadata: &md,
|
|
DecodeHook: looseDecoder,
|
|
}
|
|
|
|
decoder, err := mapstructure.NewDecoder(&config)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if err := decoder.Decode(raw); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return &out, filterUnusedKeys(md.Unused), nil
|
|
}
|