private void BuildCode(IndexerSymbol indexerSymbol) { if (indexerSymbol.IsAbstract) { return; } ImplementationBuilder implBuilder = new ImplementationBuilder(_options, _errorHandler); indexerSymbol.AddImplementation(implBuilder.BuildIndexerGetter(indexerSymbol), /* getter */ true); _implementations.Add(indexerSymbol.GetterImplementation); if (indexerSymbol.IsReadOnly == false) { indexerSymbol.AddImplementation(implBuilder.BuildPropertySetter(indexerSymbol), /* getter */ false); _implementations.Add(indexerSymbol.SetterImplementation); } if (indexerSymbol.AnonymousMethods != null) { foreach (AnonymousMethodSymbol anonymousMethod in indexerSymbol.AnonymousMethods) { Debug.Assert(anonymousMethod.Implementation != null); _implementations.Add(anonymousMethod.Implementation); } } }
public SymbolImplementation BuildIndexerSetter(IndexerSymbol indexerSymbol) { AccessorNode setterNode = ((IndexerDeclarationNode)indexerSymbol.ParseContext).SetAccessor; BlockStatementNode accessorBody = setterNode.Implementation; return(BuildImplementation((ISymbolTable)indexerSymbol.Parent, indexerSymbol, accessorBody, /* addAllParameters */ true)); }
public IndexerExpression(Expression objectReference, IndexerSymbol indexer) : base(ExpressionType.Indexer, indexer.AssociatedType, SymbolFilter.Public | SymbolFilter.InstanceMembers) { Indexer = indexer; ObjectReference = objectReference; indices = new Collection <Expression>(); }
//TODO: Investigate removing these. private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol) { // Import pseudo members that go on the class but aren't defined in mscorlib.dll // These are meant to be used by internal compiler-generated transformations etc. // and aren't meant to be referenced directly in C# code. if (memberSet == PseudoClassMembers.Script) { AddScriptSymbolPseudoMembers(classSymbol); return; } if (memberSet == PseudoClassMembers.Arguments) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Object), null, SymbolFilter.Types); Debug.Assert(objectType != null); IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); indexer.SetScriptIndexer(); classSymbol.AddMember(indexer); return; } if (memberSet == PseudoClassMembers.Dictionary) { TypeSymbol intType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Int32), null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(String), null, SymbolFilter.Types); Debug.Assert(stringType != null); // Define Dictionary.Keys MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol, symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getKeysMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keys")); classSymbol.AddMember(getKeysMethod); // Define Dictionary.Values MethodSymbol getValuesMethod = new MethodSymbol("GetValues", classSymbol, symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getValuesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("values")); classSymbol.AddMember(getValuesMethod); // Define Dictionary.GetCount MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static); countMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keyCount")); classSymbol.AddMember(countMethod); } }
public IndexerSymbol CreateIndexer(Name name, ParentSymbol parent, Name realName) { IndexerSymbol sym = (IndexerSymbol)newBasicSym(SYMKIND.SK_IndexerSymbol, name, parent); sym.setKind(SYMKIND.SK_PropertySymbol); sym.isOperator = true; Debug.Assert(sym != null); return(sym); }
private ParameterSymbol BuildParameter(ParameterNode parameterNode, IndexerSymbol indexerSymbol) { TypeSymbol parameterType = indexerSymbol.SymbolSet.ResolveType(parameterNode.Type, _symbolTable, indexerSymbol); Debug.Assert(parameterType != null); if (parameterType != null) { return(new ParameterSymbol(parameterNode.Name, indexerSymbol, parameterType, ParameterMode.In)); } return(null); }
public static void GenerateScript(ScriptGenerator generator, IndexerSymbol symbol, bool getter) { SymbolImplementation accessorImpl; if (getter) { accessorImpl = symbol.GetterImplementation; } else { accessorImpl = symbol.SetterImplementation; } GenerateImplementationScript(generator, symbol, accessorImpl); }
private IndexerSymbol BuildIndexer(IndexerDeclarationNode indexerNode, TypeSymbol typeSymbol) { TypeSymbol indexerType = typeSymbol.SymbolSet.ResolveType(indexerNode.Type, _symbolTable, typeSymbol); Debug.Assert(indexerType != null); if (indexerType != null) { IndexerSymbol indexer = new IndexerSymbol(typeSymbol, indexerType); BuildMemberDetails(indexer, typeSymbol, indexerNode, indexerNode.Attributes); if (AttributeNode.FindAttribute(indexerNode.Attributes, "IntrinsicProperty") != null) { indexer.SetIntrinsic(); } SymbolImplementationFlags implFlags = SymbolImplementationFlags.Regular; if (indexerNode.SetAccessor == null) { implFlags |= SymbolImplementationFlags.ReadOnly; } if ((indexerNode.Modifiers & Modifiers.Abstract) != 0) { implFlags |= SymbolImplementationFlags.Abstract; } else if ((indexerNode.Modifiers & Modifiers.Override) != 0) { implFlags |= SymbolImplementationFlags.Override; } indexer.SetImplementationState(implFlags); Debug.Assert(indexerNode.Parameters.Count != 0); foreach (ParameterNode parameterNode in indexerNode.Parameters) { ParameterSymbol paramSymbol = BuildParameter(parameterNode, indexer); if (paramSymbol != null) { paramSymbol.SetParseContext(parameterNode); indexer.AddParameter(paramSymbol); } } indexer.AddParameter(new ParameterSymbol("value", indexer, indexerType, ParameterMode.In)); return(indexer); } return(null); }
private static void GenerateIndexerComment(ScriptTextWriter writer, IndexerSymbol indexerSymbol) { GenerateSummaryComment(writer, indexerSymbol); if (indexerSymbol.Parameters != null) { foreach (ParameterSymbol parameterSymbol in indexerSymbol.Parameters) { GenerateParameterComment(writer, parameterSymbol); } } GenerateReturnsComment(writer, indexerSymbol.AssociatedType); }
private bool Equals(IndexerSymbol other) { return(base.Equals(other) && IndexType.Equals(other.IndexType) && ValueType.Equals(other.ValueType) && ReadOnly == other.ReadOnly); }
protected Symbol newBasicSym( SYMKIND kind, Name name, ParentSymbol parent) { // The parser creates names with PN_MISSING when attempting to recover from errors // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM) // so that they are never found when doing lookup. if (name == m_pMissingNameNode) { name = m_pMissingNameSym; } Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_NamespaceDeclaration: sym = new NamespaceDeclaration(); sym.name = name; break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: sym = new AssemblyQualifiedNamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_TransparentIdentifierMemberSymbol: sym = new TransparentIdentifierMemberSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_LabelSymbol: sym = new LabelSymbol(); sym.name = name; break; case SYMKIND.SK_GlobalAttributeDeclaration: sym = new GlobalAttributeDeclaration(); sym.name = name; break; case SYMKIND.SK_UnresolvedAggregateSymbol: sym = new UnresolvedAggregateSymbol(); sym.name = name; break; case SYMKIND.SK_InterfaceImplementationMethodSymbol: sym = new InterfaceImplementationMethodSymbol(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; case SYMKIND.SK_ParentSymbol: sym = new ParentSymbol(); sym.name = name; break; case SYMKIND.SK_IteratorFinallyMethodSymbol: sym = new IteratorFinallyMethodSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); m_pSymTable.InsertChild(parent, sym); } return (sym); }
private void ErrAppendIndexer(IndexerSymbol indexer, SubstContext pctx) { ErrAppendString("this["); ErrAppendParamList(GetTypeManager().SubstTypeArray(indexer.Params, pctx), false, indexer.isParamArray); ErrAppendChar(']'); }
private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol, BinaryExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Operator == Operator.Equals) { if (expression.LeftOperand is PropertyExpression propExpression) { Debug.Assert(propExpression.Type == ExpressionType.PropertySet); if (propExpression.ObjectReference is BaseExpression) { ClassSymbol classSymbol = (ClassSymbol)symbol.Parent; writer.Write($"{DSharpStringResources.ScriptExportMember("baseProperty")}("); writer.Write(classSymbol.FullGeneratedName); writer.Write(", '"); writer.Write(propExpression.Property.GeneratedName); writer.Write("').set.call("); writer.Write(generator.CurrentImplementation.ThisIdentifier); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } else { GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write("."); writer.Write(propExpression.Property.GeneratedName); writer.Write(" = "); GenerateExpression(generator, symbol, expression.RightOperand); } propExpression.Property.IncrementReferenceCount(); return; } if (expression.LeftOperand is IndexerExpression indexExpression) { IndexerSymbol indexerSymbol = indexExpression.Indexer; if (!indexerSymbol.UseScriptIndexer) { Debug.Assert(indexExpression.Type == ExpressionType.Indexer); if (indexExpression.ObjectReference is BaseExpression objectReference) { writer.Write(objectReference.EvaluatedType.FullGeneratedName); writer.Write(".prototype.set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write(".call("); writer.Write(generator.CurrentImplementation.ThisIdentifier); writer.Write(", "); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } else { GenerateExpression(generator, symbol, indexExpression.ObjectReference); writer.Write(".set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write("("); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } indexExpression.Indexer.IncrementReferenceCount(); return; } else if (indexerSymbol.Parent is TypeSymbol typeSymbol && !typeSymbol.IsNativeArray) { writer.Write($"ss.setItem("); GenerateExpression(generator, symbol, indexExpression.ObjectReference); writer.Write(", "); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); return; } } } else if (expression.Operator == Operator.PlusEquals || expression.Operator == Operator.MinusEquals || expression.Operator == Operator.MultiplyEquals || expression.Operator == Operator.DivideEquals || expression.Operator == Operator.ModEquals || expression.Operator == Operator.BitwiseOrEquals || expression.Operator == Operator.BitwiseAndEquals || expression.Operator == Operator.BitwiseXorEquals || expression.Operator == Operator.ShiftLeftEquals || expression.Operator == Operator.ShiftRightEquals || expression.Operator == Operator.UnsignedShiftRightEquals) { if (expression.LeftOperand is PropertyExpression propExpression) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write("."); writer.Write(propExpression.Property.GeneratedName); writer.Write(" = "); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(OperatorConverter.OperatorToString(expression.Operator - 1)); GenerateExpression(generator, symbol, expression.RightOperand); propExpression.Property.IncrementReferenceCount(); return; } } else if (expression.Operator == Operator.Is || expression.Operator == Operator.As) { TypeExpression typeExpression = expression.RightOperand as TypeExpression; Debug.Assert(typeExpression != null); writer.Write(DSharpStringResources.ScriptExportMember(string.Empty)); if (expression.Operator == Operator.Is) { writer.Write("canCast("); } else { writer.Write("safeCast("); } GenerateExpression(generator, symbol, expression.LeftOperand); writer.Write(", "); writer.Write(typeExpression.AssociatedType.FullGeneratedName); writer.Write(")"); typeExpression.AssociatedType.IncrementReferenceCount(); return; } else if (expression.Operator == Operator.EqualEqualEqual || expression.Operator == Operator.NotEqualEqual) { if (expression.RightOperand is LiteralExpression literalExpression) { // Optimize generated script to perform loose equality checks for false-y values // (null, false, 0, empty string) // TODO: This should really be happening at compilation time, rather than generation // time. Because this is happening at generation time, we get something like // if (!!x) when if(x) would suffice just so we can get // foo(!!x) where foo is a method expecting a boolean. // Doing this at compilation time would allow handling if scenarios specially. bool optimizable = false; bool checkForFalse = false; if (literalExpression.Value is bool compareValue) { optimizable = true; if (compareValue && expression.Operator == Operator.NotEqualEqual || !compareValue && expression.Operator == Operator.EqualEqualEqual) { checkForFalse = true; } } else if (literalExpression.Value is int i && i == 0) { optimizable = true; checkForFalse = expression.Operator == Operator.EqualEqualEqual; } else if (literalExpression.Value is string s && s == string.Empty) { optimizable = true; checkForFalse = expression.Operator == Operator.EqualEqualEqual; } if (optimizable) { bool parenthesize = false; writer.Write(checkForFalse ? "!" : "!!"); if (expression.LeftOperand.Parenthesized == false && (expression.LeftOperand.Type == ExpressionType.Binary || expression.LeftOperand.Type == ExpressionType.Conditional || expression.LeftOperand.Type == ExpressionType.InlineScript)) { parenthesize = true; writer.Write("("); } GenerateExpression(generator, symbol, expression.LeftOperand); if (parenthesize) { writer.Write(")"); } return; } } }
protected void ErrAppendIndexer(IndexerSymbol indexer, SubstContext pctx) { ErrAppendString("this["); ErrAppendParamList(GetTypeManager().SubstTypeArray(indexer.Params, pctx), false, indexer.isParamArray); ErrAppendChar(']'); }
private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol, BinaryExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Operator == Operator.Equals) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertySet); if (propExpression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("',"); writer.WriteTrimmed(" [ "); GenerateExpression(generator, symbol, expression.RightOperand); writer.WriteTrimmed(" ])"); } else { GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } return; } IndexerExpression indexExpression = expression.LeftOperand as IndexerExpression; if ((indexExpression != null) && !indexExpression.Indexer.IsIntrinsic) { Debug.Assert(indexExpression.Type == ExpressionType.Indexer); if (indexExpression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'set_"); writer.Write(indexExpression.Indexer.GeneratedName); writer.Write("',"); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.WriteTrimmed(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.WriteTrimmed(" ])"); } else { IndexerSymbol indexerSymbol = indexExpression.Indexer; GenerateExpression(generator, symbol, indexExpression.ObjectReference); writer.Write(".set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write("("); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.WriteTrimmed(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } return; } } else if ((expression.Operator == Operator.PlusEquals) || (expression.Operator == Operator.MinusEquals) || (expression.Operator == Operator.MultiplyEquals) || (expression.Operator == Operator.DivideEquals) || (expression.Operator == Operator.ModEquals) || (expression.Operator == Operator.BitwiseOrEquals) || (expression.Operator == Operator.BitwiseAndEquals) || (expression.Operator == Operator.BitwiseXorEquals) || (expression.Operator == Operator.ShiftLeftEquals) || (expression.Operator == Operator.ShiftRightEquals) || (expression.Operator == Operator.UnsignedShiftRightEquals)) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".get_"); writer.Write(propExpression.Property.GeneratedName); writer.WriteTrimmed("()"); writer.WriteTrimmed(OperatorConverter.OperatorToString(expression.Operator - 1)); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); return; } } else if ((expression.Operator == Operator.Is) || (expression.Operator == Operator.As)) { TypeExpression typeExpression = expression.RightOperand as TypeExpression; Debug.Assert(typeExpression != null); writer.Write("Type."); if (expression.Operator == Operator.Is) { writer.Write("canCast("); } else { writer.Write("safeCast("); } GenerateExpression(generator, symbol, expression.LeftOperand); writer.WriteTrimmed(", "); writer.Write(typeExpression.AssociatedType.FullGeneratedName); writer.Write(")"); return; } else if ((expression.Operator == Operator.EqualEqualEqual) || (expression.Operator == Operator.NotEqualEqual)) { LiteralExpression literalExpression = expression.RightOperand as LiteralExpression; if (literalExpression != null) { // Optimize generated script to perform loose equality checks for false-y values // (null, false, 0, empty string) // TODO: This should really be happening at compilation time, rather than generation // time. Because this is happening at generation time, we get something like // if (!!x) when if(x) would suffice just so we can get // foo(!!x) where foo is a method expecting a boolean. // Doing this at compilation time would allow handling if scenarios specially. bool optimizable = false; bool checkForFalse = false; if (literalExpression.Value is bool) { optimizable = true; bool compareValue = (bool)literalExpression.Value; if ((compareValue && (expression.Operator == Operator.NotEqualEqual)) || (!compareValue && (expression.Operator == Operator.EqualEqualEqual))) { checkForFalse = true; } } else if ((literalExpression.Value is int) && (((int)literalExpression.Value) == 0)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } else if ((literalExpression.Value is string) && ((string)literalExpression.Value == String.Empty)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } if (optimizable) { bool parenthesize = false; writer.Write(checkForFalse ? "!" : "!!"); if ((expression.LeftOperand.Parenthesized == false) && ((expression.LeftOperand.Type == ExpressionType.Binary) || (expression.LeftOperand.Type == ExpressionType.Conditional) || (expression.LeftOperand.Type == ExpressionType.InlineScript))) { parenthesize = true; writer.Write("("); } GenerateExpression(generator, symbol, expression.LeftOperand); if (parenthesize) { writer.Write(")"); } return; } } } GenerateExpression(generator, symbol, expression.LeftOperand); writer.WriteTrimmed(OperatorConverter.OperatorToString(expression.Operator)); GenerateExpression(generator, symbol, expression.RightOperand); }
private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol) { // Import pseudo members that go on the class but aren't defined in mscorlib.dll // These are meant to be used by internal compiler-generated transformations etc. // and aren't meant to be referenced directly in C# code. if (memberSet == PseudoClassMembers.Script) { TypeSymbol boolType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Boolean", null, SymbolFilter.Types); Debug.Assert(boolType != null); TypeSymbol intType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Int32", null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol floatType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Single", null, SymbolFilter.Types); Debug.Assert(floatType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(stringType != null); // Define the Escape, Unescape, encodeURI, decodeURI, encodeURIComponent, decodeURIComponent methods MethodSymbol escapeMethod = new MethodSymbol("Escape", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(escapeMethod); MethodSymbol unescapeMethod = new MethodSymbol("Unescape", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(unescapeMethod); MethodSymbol encodeURIMethod = new MethodSymbol("EncodeUri", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); encodeURIMethod.SetTransformedName("encodeURI"); classSymbol.AddMember(encodeURIMethod); MethodSymbol decodeURIMethod = new MethodSymbol("DecodeUri", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); decodeURIMethod.SetTransformedName("decodeURI"); classSymbol.AddMember(decodeURIMethod); MethodSymbol encodeURIComponentMethod = new MethodSymbol("EncodeUriComponent", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); encodeURIComponentMethod.SetTransformedName("encodeURIComponent"); classSymbol.AddMember(encodeURIComponentMethod); MethodSymbol decodeURIComponentMethod = new MethodSymbol("DecodeUriComponent", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); decodeURIComponentMethod.SetTransformedName("decodeURIComponent"); classSymbol.AddMember(decodeURIComponentMethod); return; } if (memberSet == PseudoClassMembers.Arguments) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); indexer.SetIntrinsic(); classSymbol.AddMember(indexer); return; } if (memberSet == PseudoClassMembers.Type) { // Define the Type.GetInstanceType static method which provides the functionality of // Object.GetType instance method. We don't extend Object.prototype in script to add // GetType, since we want to keep Object's protoype clean of any extensions. // // We create this symbol here, so that later the ExpressionBuilder can transform // calls to Object.GetType to this. TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); TypeSymbol typeType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Type", null, SymbolFilter.Types); Debug.Assert(objectType != null); MethodSymbol getTypeMethod = new MethodSymbol("GetInstanceType", classSymbol, typeType, MemberVisibility.Public | MemberVisibility.Static); getTypeMethod.AddParameter(new ParameterSymbol("instance", getTypeMethod, objectType, ParameterMode.In)); classSymbol.AddMember(getTypeMethod); return; } if (memberSet == PseudoClassMembers.Dictionary) { TypeSymbol intType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Int32", null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol boolType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Boolean", null, SymbolFilter.Types); Debug.Assert(boolType != null); TypeSymbol voidType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Void", null, SymbolFilter.Types); Debug.Assert(boolType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(boolType != null); // Define Dictionary.Keys MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol, _symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getKeysMethod.SetTransformedName("keys"); classSymbol.AddMember(getKeysMethod); // Define Dictionary.GetCount MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(countMethod); // Define Dictionary.ClearKeys MethodSymbol clearMethod = new MethodSymbol("ClearKeys", classSymbol, voidType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(clearMethod); // Define Dictionary.DeleteKey MethodSymbol deleteMethod = new MethodSymbol("DeleteKey", classSymbol, voidType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(deleteMethod); // Define Dictionary.KeyExists MethodSymbol existsMethod = new MethodSymbol("KeyExists", classSymbol, boolType, MemberVisibility.Public | MemberVisibility.Static); classSymbol.AddMember(existsMethod); return; } if (memberSet == PseudoClassMembers.String) { // In script, String.replace replaces only the first occurrence of a string // whereas in C# all occurrences are replaced. // Replace becomes replaceAll (a method we add) in generated script // ReplaceFirst becomes replace in generated script. // ReplaceRegex also becomes replace in generated script. (We added ReplaceRegex so // it could be mapped to the native replace method, rather than out replaceAll // extension) MethodSymbol replaceFirstMethod = (MethodSymbol)classSymbol.GetMember("ReplaceFirst"); Debug.Assert(replaceFirstMethod != null); replaceFirstMethod.SetTransformedName("replace"); MethodSymbol replaceMethod = (MethodSymbol)classSymbol.GetMember("Replace"); Debug.Assert(replaceMethod != null); replaceMethod.SetTransformedName("replaceAll"); MethodSymbol replaceRegexMethod = (MethodSymbol)classSymbol.GetMember("ReplaceRegex"); Debug.Assert(replaceRegexMethod != null); replaceRegexMethod.SetTransformedName("replace"); } }
private void ImportProperties(TypeSymbol typeSymbol) { TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (PropertyDefinition property in type.Properties) { if (property.IsSpecialName) { continue; } if (property.GetMethod == null) { continue; } if (property.GetMethod.IsPrivate || property.GetMethod.IsAssembly || property.GetMethod.IsFamilyAndAssembly) { continue; } string propertyName = property.Name; bool scriptField = MetadataHelpers.ShouldTreatAsScriptField(property); // TODO: Why are we ignoring the other bits... // bool dummyPreserveName; // bool preserveCase; // string dummyName = MetadataHelpers.GetScriptName(property, out dummyPreserveName, out preserveCase); TypeSymbol propertyType = ResolveType(property.PropertyType); if (propertyType == null) { continue; } PropertySymbol propertySymbol = null; if (property.Parameters.Count != 0) { IndexerSymbol indexerSymbol = new IndexerSymbol(typeSymbol, propertyType); ImportMemberDetails(indexerSymbol, property.GetMethod, property); if (scriptField) { indexerSymbol.SetScriptIndexer(); } propertySymbol = indexerSymbol; // propertySymbol.SetNameCasing(preserveCase); } else { if (scriptField) { // Properties marked with this attribute are to be thought of as // fields. If they are read-only, the C# compiler will enforce that, // so we don't have to worry about making them read-write via a field // instead of a property FieldSymbol fieldSymbol = new FieldSymbol(propertyName, typeSymbol, propertyType); ImportMemberDetails(fieldSymbol, property.GetMethod, property); string transformedName = MetadataHelpers.GetTransformedName(property); if (string.IsNullOrEmpty(transformedName) == false) { fieldSymbol.SetTransformName(transformedName); } typeSymbol.AddMember(fieldSymbol); } else { propertySymbol = new PropertySymbol(propertyName, typeSymbol, propertyType); ImportMemberDetails(propertySymbol, property.GetMethod, property); propertySymbol.SetNameCasing(true); string transformedName = MetadataHelpers.GetTransformedName(property.GetMethod); if (string.IsNullOrEmpty(transformedName) == false) { propertySymbol.SetTransformedName(transformedName); } } } if (propertySymbol != null) { SymbolImplementationFlags implFlags = SymbolImplementationFlags.Regular; if (property.SetMethod == null) { implFlags |= SymbolImplementationFlags.ReadOnly; } if (property.GetMethod.IsAbstract) { implFlags |= SymbolImplementationFlags.Abstract; } propertySymbol.SetImplementationState(implFlags); typeSymbol.AddMember(propertySymbol); } } }
public BoundElementAccessExpression(ElementAccessExpressionSyntax syntax, BoundExpression expression, BoundExpression index, IndexerSymbol indexer) : base(BoundNodeKind.ElementAccessExpression, syntax) { Expression = expression; Index = index; Type = indexer.AssociatedType; }
private Symbol NewBasicSymbol( SYMKIND kind, Name name, ParentSymbol parent) { Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); _symbolTable.InsertChild(parent, sym); } return(sym); }
private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol) { // Import pseudo members that go on the class but aren't defined in mscorlib.dll // These are meant to be used by internal compiler-generated transformations etc. // and aren't meant to be referenced directly in C# code. if (memberSet == PseudoClassMembers.Script) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(stringType != null); TypeSymbol boolType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Boolean", null, SymbolFilter.Types); Debug.Assert(boolType != null); TypeSymbol dateType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Date", null, SymbolFilter.Types); Debug.Assert(dateType != null); // Enumerate - IEnumerable.GetEnumerator gets mapped to this MethodSymbol enumerateMethod = new MethodSymbol("Enumerate", classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); enumerateMethod.SetAlias("ss.enumerate"); enumerateMethod.AddParameter(new ParameterSymbol("obj", enumerateMethod, objectType, ParameterMode.In)); classSymbol.AddMember(enumerateMethod); // TypeName - Type.Name gets mapped to this MethodSymbol typeNameMethod = new MethodSymbol("GetTypeName", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); typeNameMethod.SetAlias("ss.typeName"); typeNameMethod.AddParameter(new ParameterSymbol("obj", typeNameMethod, objectType, ParameterMode.In)); classSymbol.AddMember(typeNameMethod); // CompareDates - Date equality checks get converted to call to compareDates MethodSymbol compareDatesMethod = new MethodSymbol("CompareDates", classSymbol, boolType, MemberVisibility.Public | MemberVisibility.Static); compareDatesMethod.SetAlias("ss.compareDates"); compareDatesMethod.AddParameter(new ParameterSymbol("d1", compareDatesMethod, dateType, ParameterMode.In)); compareDatesMethod.AddParameter(new ParameterSymbol("d2", compareDatesMethod, dateType, ParameterMode.In)); classSymbol.AddMember(compareDatesMethod); return; } if (memberSet == PseudoClassMembers.Arguments) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); indexer.SetScriptIndexer(); classSymbol.AddMember(indexer); return; } if (memberSet == PseudoClassMembers.Dictionary) { TypeSymbol intType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Int32", null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(stringType != null); // Define Dictionary.Keys MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol, _symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getKeysMethod.SetAlias("ss.keys"); classSymbol.AddMember(getKeysMethod); // Define Dictionary.GetCount MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static); countMethod.SetAlias("ss.keyCount"); classSymbol.AddMember(countMethod); return; } }
protected Symbol newBasicSym( SYMKIND kind, Name name, ParentSymbol parent) { // The parser creates names with PN_MISSING when attempting to recover from errors // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM) // so that they are never found when doing lookup. if (name == m_pMissingNameNode) { name = m_pMissingNameSym; } Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_NamespaceDeclaration: sym = new NamespaceDeclaration(); sym.name = name; break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: sym = new AssemblyQualifiedNamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_TransparentIdentifierMemberSymbol: sym = new TransparentIdentifierMemberSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_LabelSymbol: sym = new LabelSymbol(); sym.name = name; break; case SYMKIND.SK_GlobalAttributeDeclaration: sym = new GlobalAttributeDeclaration(); sym.name = name; break; case SYMKIND.SK_UnresolvedAggregateSymbol: sym = new UnresolvedAggregateSymbol(); sym.name = name; break; case SYMKIND.SK_InterfaceImplementationMethodSymbol: sym = new InterfaceImplementationMethodSymbol(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; case SYMKIND.SK_ParentSymbol: sym = new ParentSymbol(); sym.name = name; break; case SYMKIND.SK_IteratorFinallyMethodSymbol: sym = new IteratorFinallyMethodSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); m_pSymTable.InsertChild(parent, sym); } return(sym); }
public IndexerSymbolSignature(IndexerSymbol symbol) { Symbol = symbol; }
private bool Equals(IndexerSymbol other) { return base.Equals(other) && IndexType.Equals(other.IndexType) && ValueType.Equals(other.ValueType) && ReadOnly == other.ReadOnly; }