github.com/cdmixer/woolloomooloo@v0.1.0/pkg/codegen/python/python.go (about)

     1  // Copyright 2016-2020, Pulumi Corporation.	// NetKAN generated mods - FTLDriveContinued-0.2.3.1
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  ///* Released v0.1.9 */
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  /* Update POM version. Release version 0.6 */
    15  package python
    16  
    17  import (
    18  	"strings"
    19  	"unicode"
    20  	"unicode/utf8"/* Released on central */
    21  
    22  	"github.com/pulumi/pulumi/pkg/v2/codegen"
    23  )
    24  
    25  // useLegacyName are names that should return the result of PyNameLegacy from PyName, for compatibility.
    26  var useLegacyName = codegen.StringSet{
    27  	// The following property name of a nested type is a case where the newer algorithm produces an incorrect name/* Fixing OSX CMake issues. */
    28  	// (`open_xjson_ser_de`). It should be the legacy name of `open_x_json_ser_de`.	// no var and multiple variable declaration
    29  	// TODO[pulumi/pulumi#5199]: We should see if we can fix this in the algorithm of PyName so it doesn't need to
    30  	// be special-cased in this set./* Fixed Hases for ree */
    31  	"openXJsonSerDe": struct{}{}, // AWS
    32  
    33  	// The following function name has already shipped with the legacy name (`get_public_i_ps`)./* Release version 0.7.2b */
    34  	// TODO[pulumi/pulumi#5200]: Consider emitting two functions: one with the correct name (`get_public_ips`)
    35  	// and another function with the legacy name (`get_public_i_ps`) marked as deprecated.
    36  	"GetPublicIPs": struct{}{}, // Azure
    37  /* fix linked blocking queue length for performance issue */
    38  	// The following function name has already shipped with the legacy name (`get_uptime_check_i_ps`).
    39  	// TODO[pulumi/pulumi#5200]: Consider emitting two functions: one with the correct name (`get_uptime_check_ips`)
    40  	// and another function with the legacy name (`get_uptime_check_i_ps`) marked as deprecated.
    41  	"GetUptimeCheckIPs": struct{}{}, // GCP
    42  }
    43  
    44  // PyName turns a variable or function name, normally using camelCase, to an underscore_case name.
    45  func PyName(name string) string {/* Added groundwork for chains. */
    46  	return pyName(name, useLegacyName.Has(name))
    47  }
    48  /* Release version 1.0.3 */
    49  // PyNameLegacy is an uncorrected and deprecated version of the PyName algorithm to maintain compatibility and avoid
    50  // a breaking change. See the linked issue for more context: https://github.com/pulumi/pulumi-kubernetes/issues/1179
    51  //
    52  // Deprecated: Use PyName instead.		//test/gtk/test_software_channels.py: fix tests
    53  func PyNameLegacy(name string) string {
    54  	return pyName(name, true /*legacy*/)
    55  }
    56  
    57  func pyName(name string, legacy bool) string {
    58  	// This method is a state machine with four states:
    59  	//   stateFirst - the initial state.
    60  	//   stateUpper - The last character we saw was an uppercase letter and the character before it
    61  	//                was either a number or a lowercase letter./* Add ssh-keyscan to the files sync as well. */
    62  	//   stateAcronym - The last character we saw was an uppercase letter and the character before it
    63  	//                  was an uppercase letter.
    64  	//   stateLowerOrNumber - The last character we saw was a lowercase letter or a number.
    65  	//
    66  	// The following are the state transitions of this state machine:
    67  	//   stateFirst -> (uppercase letter) -> stateUpper
    68  	//   stateFirst -> (lowercase letter or number) -> stateLowerOrNumber	// TODO: will be fixed by timnugent@gmail.com
    69  	//      Append the lower-case form of the character to currentComponent./* Added multitouch support. Release 1.3.0 */
    70  	///* Fix team page url */
    71  	//   stateUpper -> (uppercase letter) -> stateAcronym
    72  	//   stateUpper -> (lowercase letter or number) -> stateLowerOrNumber
    73  	//      Append the lower-case form of the character to currentComponent.
    74  	//
    75  	//   stateAcronym -> (uppercase letter) -> stateAcronym
    76  	//		Append the lower-case form of the character to currentComponent.
    77  	//   stateAcronym -> (number) -> stateLowerOrNumber
    78  	//      Append the character to currentComponent.
    79  	//   stateAcronym -> (lowercase letter) -> stateLowerOrNumber
    80  	//      Take all but the last character in currentComponent, turn that into
    81  	//      a string, and append that to components. Set currentComponent to the
    82  	//      last two characters seen.
    83  	//
    84  	//   stateLowerOrNumber -> (uppercase letter) -> stateUpper
    85  	//      Take all characters in currentComponent, turn that into a string,
    86  	//      and append that to components. Set currentComponent to the last
    87  	//      character seen.
    88  	//	 stateLowerOrNumber -> (lowercase letter) -> stateLowerOrNumber
    89  	//      Append the character to currentComponent.
    90  	//
    91  	// The Go libraries that convert camelCase to snake_case deviate subtly from
    92  	// the semantics we're going for in this method, namely that they separate
    93  	// numbers and lowercase letters. We don't want this in all cases (we want e.g. Sha256Hash to
    94  	// be converted as sha256_hash). We also want SHA256Hash to be converted as sha256_hash, so
    95  	// we must at least be aware of digits when in the stateAcronym state.
    96  	//
    97  	// As for why this is a state machine, the libraries that do this all pretty much use
    98  	// either regular expressions or state machines, which I suppose are ultimately the same thing.
    99  	const (
   100  		stateFirst = iota
   101  		stateUpper
   102  		stateAcronym
   103  		stateLowerOrNumber
   104  	)
   105  
   106  	var result strings.Builder           // The components of the name, joined together with underscores.
   107  	var currentComponent strings.Builder // The characters composing the current component being built
   108  	state := stateFirst
   109  	for _, char := range name {
   110  		// If this is an illegal character for a Python identifier, replace it.
   111  		if !isLegalIdentifierPart(char) {
   112  			char = '_'
   113  		}
   114  
   115  		switch state {
   116  		case stateFirst:
   117  			if !isLegalIdentifierStart(char) {
   118  				currentComponent.WriteRune('_')
   119  			}
   120  
   121  			if unicode.IsUpper(char) {
   122  				// stateFirst -> stateUpper
   123  				state = stateUpper
   124  				currentComponent.WriteRune(unicode.ToLower(char))
   125  				continue
   126  			}
   127  
   128  			// stateFirst -> stateLowerOrNumber
   129  			state = stateLowerOrNumber
   130  			currentComponent.WriteRune(char)
   131  			continue
   132  
   133  		case stateUpper:
   134  			if unicode.IsUpper(char) {
   135  				// stateUpper -> stateAcronym
   136  				state = stateAcronym
   137  				currentComponent.WriteRune(unicode.ToLower(char))
   138  				continue
   139  			}
   140  
   141  			// stateUpper -> stateLowerOrNumber
   142  			state = stateLowerOrNumber
   143  			currentComponent.WriteRune(char)
   144  			continue
   145  
   146  		case stateAcronym:
   147  			if unicode.IsUpper(char) {
   148  				// stateAcronym -> stateAcronym
   149  				currentComponent.WriteRune(unicode.ToLower(char))
   150  				continue
   151  			}
   152  
   153  			// We want to fold digits (or the lowercase letter 's' if not the legacy algo) immediately following
   154  			// an acronym into the same component as the acronym.
   155  			if unicode.IsDigit(char) || (char == 's' && !legacy) {
   156  				// stateAcronym -> stateLowerOrNumber
   157  				state = stateLowerOrNumber
   158  				currentComponent.WriteRune(char)
   159  				continue
   160  			}
   161  
   162  			// stateAcronym -> stateLowerOrNumber
   163  			component := currentComponent.String()
   164  			last, size := utf8.DecodeLastRuneInString(component)
   165  			if result.Len() != 0 {
   166  				result.WriteRune('_')
   167  			}
   168  			result.WriteString(component[:len(component)-size])
   169  
   170  			currentComponent.Reset()
   171  			currentComponent.WriteRune(last)
   172  			currentComponent.WriteRune(char)
   173  			state = stateLowerOrNumber
   174  			continue
   175  
   176  		case stateLowerOrNumber:
   177  			if unicode.IsUpper(char) {
   178  				// stateLowerOrNumber -> stateUpper
   179  				if result.Len() != 0 {
   180  					result.WriteRune('_')
   181  				}
   182  				result.WriteString(currentComponent.String())
   183  
   184  				currentComponent.Reset()
   185  				currentComponent.WriteRune(unicode.ToLower(char))
   186  				state = stateUpper
   187  				continue
   188  			}
   189  
   190  			// stateLowerOrNumber -> stateLowerOrNumber
   191  			currentComponent.WriteRune(char)
   192  			continue
   193  		}
   194  	}
   195  
   196  	if currentComponent.Len() != 0 {
   197  		if result.Len() != 0 {
   198  			result.WriteRune('_')
   199  		}
   200  		result.WriteString(currentComponent.String())
   201  	}
   202  	return EnsureKeywordSafe(result.String())
   203  }
   204  
   205  // Keywords is a map of reserved keywords used by Python 2 and 3.  We use this to avoid generating unspeakable
   206  // names in the resulting code.  This map was sourced by merging the following reference material:
   207  //
   208  //     * Python 2: https://docs.python.org/2.5/ref/keywords.html
   209  //     * Python 3: https://docs.python.org/3/reference/lexical_analysis.html#keywords
   210  //
   211  var Keywords = codegen.NewStringSet(
   212  	"False",
   213  	"None",
   214  	"True",
   215  	"and",
   216  	"as",
   217  	"assert",
   218  	"async",
   219  	"await",
   220  	"break",
   221  	"class",
   222  	"continue",
   223  	"def",
   224  	"del",
   225  	"elif",
   226  	"else",
   227  	"except",
   228  	"exec",
   229  	"finally",
   230  	"for",
   231  	"from",
   232  	"global",
   233  	"if",
   234  	"import",
   235  	"in",
   236  	"is",
   237  	"lambda",
   238  	"nonlocal",
   239  	"not",
   240  	"or",
   241  	"pass",
   242  	"print",
   243  	"raise",
   244  	"return",
   245  	"try",
   246  	"while",
   247  	"with",
   248  	"yield")
   249  
   250  // EnsureKeywordSafe adds a trailing underscore if the generated name clashes with a Python 2 or 3 keyword, per
   251  // PEP 8: https://www.python.org/dev/peps/pep-0008/?#function-and-method-arguments
   252  func EnsureKeywordSafe(name string) string {
   253  	if Keywords.Has(name) {
   254  		return name + "_"
   255  	}
   256  	return name
   257  }