source: EcnlProtoTool/trunk/webapp/webmrbc/Names.cs@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 5.5 KB
Line 
1/**
2* @license
3* Visual Blocks Editor
4*
5* Copyright 2012 Google Inc.
6* https://developers.google.com/blockly/
7*
8* Licensed under the Apache License, Version 2.0 (the "License");
9* you may not use this file except in compliance with the License.
10* You may obtain a copy of the License at
11*
12* http://www.apache.org/licenses/LICENSE-2.0
13*
14* Unless required by applicable law or agreed to in writing, software
15* distributed under the License is distributed on an "AS IS" BASIS,
16* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17* See the License for the specific language governing permissions and
18* limitations under the License.
19*//**
20* @fileoverview Utility functions for handling variables and procedure names.
21* @author fraser@google.com (Neil Fraser)
22*/
23using System;
24using System.Collections.Generic;
25using System.Runtime.InteropServices;
26using Bridge;
27using Bridge.Text.RegularExpressions;
28
29namespace WebMrbc
30{
31 [ComVisible(true)]
32 public class Names
33 {
34 string variablePrefix_;
35 Dictionary<string, bool> reservedDict_;
36 Dictionary<string, string> db_;
37 Dictionary<string, bool> dbReverse_;
38
39 /// <summary>
40 /// Class for a database of entity names (variables, functions, etc).
41 /// </summary>
42 /// <param name="reservedWords">A comma-separated string of words that are
43 /// illegal for use as names in a language (e.g. 'new,if,this,...').</param>
44 /// <param name="opt_variablePrefix">Some languages need a '$' or a namespace
45 /// before all variable names.</param>
46 public Names(string reservedWords, string opt_variablePrefix = null)
47 {
48 this.variablePrefix_ = opt_variablePrefix == null ? "" : opt_variablePrefix;
49 this.reservedDict_ = new Dictionary<string, bool>();
50 if (reservedWords != null) {
51 var splitWords = reservedWords.Split(',');
52 for (var i = 0; i < splitWords.Length; i++) {
53 this.reservedDict_[splitWords[i]] = true;
54 }
55 }
56 this.reset();
57 }
58
59 /**
60 * When JavaScript (or most other languages) is generated, variable 'foo' and
61 * procedure 'foo' would collide. However, Blockly has no such problems since
62 * variable get 'foo' and procedure call 'foo' are unambiguous.
63 * Therefore, Blockly keeps a separate type name to disambiguate.
64 * getName('foo', 'variable') -> 'foo'
65 * getName('foo', 'procedure') -> 'foo2'
66 */
67
68 /// <summary>
69 /// Empty the database and start from scratch. The reserved words are kept.
70 /// </summary>
71 public void reset()
72 {
73 this.db_ = new Dictionary<string, string>();
74 this.dbReverse_ = new Dictionary<string, bool>();
75 }
76
77 /// <summary>
78 /// Convert a Blockly entity name to a legal exportable entity name.
79 /// </summary>
80 /// <param name="name">The Blockly entity name (no constraints).</param>
81 /// <param name="type">The type of entity in Blockly
82 /// ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).</param>
83 /// <returns>An entity name legal for the exported language.</returns>
84 public string getName(string name, string type)
85 {
86 var normalized = name.ToLower() + '_' + type;
87 var prefix = (type == Blockly.Variables.NAME_TYPE) ?
88 this.variablePrefix_ : "";
89 if (this.db_.ContainsKey(normalized)) {
90 return prefix + this.db_[normalized];
91 }
92 var safeName = this.getDistinctName(name, type);
93 this.db_[normalized] = safeName.Substr(prefix.Length);
94 return safeName;
95 }
96
97 /// <summary>
98 /// Convert a Blockly entity name to a legal exportable entity name.
99 /// Ensure that this is a new name not overlapping any previously defined name.
100 /// Also check against list of reserved words for the current language and
101 /// ensure name doesn't collide.
102 /// </summary>
103 /// <param name="name">The Blockly entity name (no constraints).</param>
104 /// <param name="type">The type of entity in Blockly
105 /// ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).</param>
106 /// <returns>An entity name legal for the exported language.</returns>
107 public string getDistinctName(string name, string type)
108 {
109 var safeName = this.safeName_(name);
110 var i = 0;
111 while (this.dbReverse_.ContainsKey(safeName + ((i == 0) ? "" : i.ToString())) ||
112 this.reservedDict_.ContainsKey(safeName + i.ToString())) {
113 // Collision with existing name. Create a unique name.
114 i++;
115 }
116 if (i > 0)
117 safeName += i;
118 this.dbReverse_[safeName] = true;
119 var prefix = (type == Blockly.Variables.NAME_TYPE) ?
120 this.variablePrefix_ : "";
121 return prefix + safeName;
122 }
123
124 /// <summary>
125 /// Given a proposed entity name, generate a name that conforms to the
126 /// [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for
127 /// variables.
128 /// </summary>
129 /// <param name="name">Potentially illegal entity name.</param>
130 /// <returns>Safe entity name.</returns>
131 public string safeName_(string name)
132 {
133 if (name == null) {
134 name = "unnamed";
135 }
136 else {
137 // Unfortunately names in non-latin characters will look like
138 // _E9_9F_B3_E4_B9_90 which is pretty meaningless.
139 name = Script.EncodeURI(name.Replace(new Regex(" "), "_").Replace(new Regex(@"[^\w]"), "_"));
140 // Most languages don't allow names with leading numbers.
141 if ("0123456789".IndexOf(name[0]) != -1) {
142 name = "my_" + name;
143 }
144 }
145 return name;
146 }
147
148 /// <summary>
149 /// Do the given two entity names refer to the same entity?
150 /// Blockly names are case-insensitive.
151 /// </summary>
152 /// <param name="name1">First name.</param>
153 /// <param name="name2">Second name.</param>
154 /// <returns>True if names are the same.</returns>
155 public bool equals(string name1, string name2)
156 {
157 return name1.ToLower() == name2.ToLower();
158 }
159 }
160}
Note: See TracBrowser for help on using the repository browser.