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
 | 
						|
}
 |