github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/types/goversion.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package types
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"strconv"
    11  
    12  	"github.com/go-asm/go/goversion"
    13  	"github.com/go-asm/go/lazyregexp"
    14  
    15  	"github.com/go-asm/go/cmd/compile/base"
    16  )
    17  
    18  // A lang is a language version broken into major and minor numbers.
    19  type lang struct {
    20  	major, minor int
    21  }
    22  
    23  // langWant is the desired language version set by the -lang flag.
    24  // If the -lang flag is not set, this is the zero value, meaning that
    25  // any language version is supported.
    26  var langWant lang
    27  
    28  // AllowsGoVersion reports whether local package is allowed
    29  // to use Go version major.minor.
    30  func AllowsGoVersion(major, minor int) bool {
    31  	if langWant.major == 0 && langWant.minor == 0 {
    32  		return true
    33  	}
    34  	return langWant.major > major || (langWant.major == major && langWant.minor >= minor)
    35  }
    36  
    37  // ParseLangFlag verifies that the -lang flag holds a valid value, and
    38  // exits if not. It initializes data used by langSupported.
    39  func ParseLangFlag() {
    40  	if base.Flag.Lang == "" {
    41  		return
    42  	}
    43  
    44  	var err error
    45  	langWant, err = parseLang(base.Flag.Lang)
    46  	if err != nil {
    47  		log.Fatalf("invalid value %q for -lang: %v", base.Flag.Lang, err)
    48  	}
    49  
    50  	if def := currentLang(); base.Flag.Lang != def {
    51  		defVers, err := parseLang(def)
    52  		if err != nil {
    53  			log.Fatalf("internal error parsing default lang %q: %v", def, err)
    54  		}
    55  		if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
    56  			log.Fatalf("invalid value %q for -lang: max known version is %q", base.Flag.Lang, def)
    57  		}
    58  	}
    59  }
    60  
    61  // parseLang parses a -lang option into a langVer.
    62  func parseLang(s string) (lang, error) {
    63  	matches := goVersionRE.FindStringSubmatch(s)
    64  	if matches == nil {
    65  		return lang{}, fmt.Errorf(`should be something like "go1.12"`)
    66  	}
    67  	major, err := strconv.Atoi(matches[1])
    68  	if err != nil {
    69  		return lang{}, err
    70  	}
    71  	minor, err := strconv.Atoi(matches[2])
    72  	if err != nil {
    73  		return lang{}, err
    74  	}
    75  	return lang{major: major, minor: minor}, nil
    76  }
    77  
    78  // currentLang returns the current language version.
    79  func currentLang() string {
    80  	return fmt.Sprintf("go1.%d", goversion.Version)
    81  }
    82  
    83  // goVersionRE is a regular expression that matches the valid
    84  // arguments to the -lang flag.
    85  var goVersionRE = lazyregexp.New(`^go([1-9]\d*)\.(0|[1-9]\d*)$`)