protected virtual List WalkMemberChain(MemberReferenceExpression memberRef) { List chain = new List(); while (true) { MemberReferenceExpression container = memberRef.Target as MemberReferenceExpression; if (null == container || (IsSpecialMemberTarget(container) && IsReadOnlyMember(container))) { Warnings.Add( CompilerWarningFactory.AssignmentToTemporary(memberRef)); return(null); } if (IsSpecialMemberTarget(container) && EntityType.Field != container.Entity.EntityType) { chain.Insert(0, new ChainItem(container)); } if (IsTerminalReferenceNode(container.Target)) { break; } memberRef = container; } return(chain); }
//this method returns -1 if it doesn't detect unreachable code //else it returns the index of the first unreachable in block.Statements private int DetectUnreachableCode(Block block, Statement limit) { var unreachable = false; var idx = 0; foreach (var stmt in block.Statements) { //HACK: __switch__ builtin function is hard to detect/handle // within this context, let's ignore whatever is after __switch__ if (IsSwitchBuiltin(stmt)) { return(-1); //ignore followings } if (unreachable && stmt is LabelStatement) { return(-1); } if (stmt == limit) { unreachable = true; } else if (unreachable) { if (!stmt.IsSynthetic) { Warnings.Add(CompilerWarningFactory.UnreachableCodeDetected(stmt)); } return(idx); } idx++; } return(-1); }
//returns true if a stub has been created, false otherwise. //TODO: add entity argument to the method to not need return type? bool AbstractMemberNotImplemented(ClassDefinition node, TypeReference baseTypeRef, IMember member) { if (IsValueType(node)) { Error(CompilerErrorFactory.ValueTypeCantHaveAbstractMember(baseTypeRef, GetType(node), member)); return(false); } if (!node.IsAbstract) { //BEHAVIOR >= 0.7.7: (see BOO-789 for details) //create a stub for this not implemented member //it will raise a NotImplementedException if called at runtime TypeMember m = CodeBuilder.CreateStub(node, member); CompilerWarning warning = null; if (null != m) { warning = CompilerWarningFactory.AbstractMemberNotImplementedStubCreated(baseTypeRef, GetType(node), member); if (m.NodeType != NodeType.Property || null == node.Members[m.Name]) { AddStub(node, m); } } else { warning = CompilerWarningFactory.AbstractMemberNotImplemented(baseTypeRef, GetType(node), member); _newAbstractClasses.AddUnique(node); } Warnings.Add(warning); return(null != m); } return(false); }
override public void OnReferenceExpression(ReferenceExpression node) { IExternalEntity member = node.Entity as IExternalEntity; if (member == null) //extract to OnInternalReferenceExpression { OnInternalReferenceExpression(node); return; } System.Attribute[] attributes = System.Attribute.GetCustomAttributes(member.MemberInfo, typeof(ObsoleteAttribute)); foreach (ObsoleteAttribute attr in attributes) { if (attr.IsError) { Errors.Add( CompilerErrorFactory.Obsolete(node, member.ToString(), attr.Message)); } else { Warnings.Add( CompilerWarningFactory.Obsolete(node, member.ToString(), attr.Message)); } } }
override public void LeaveBinaryExpression(BinaryExpression node) { if (CheckExpressionType(node.Right)) { CheckExpressionType(node.Left); } if (BinaryOperatorType.ReferenceEquality == node.Operator) { if (IsTypeReference(node.Right)) { Warnings.Add( CompilerWarningFactory.IsInsteadOfIsa(node)); } } //check that the assignment or comparison is meaningful if (BinaryOperatorType.Assign == node.Operator || AstUtil.GetBinaryOperatorKind(node) == BinaryOperatorKind.Comparison) { if (AreSameExpressions(node.Left, node.Right)) { Warnings.Add( (BinaryOperatorType.Assign == node.Operator) ? CompilerWarningFactory.AssignmentToSameVariable(node) : CompilerWarningFactory.ComparisonWithSameVariable(node) ); } else if (BinaryOperatorType.Assign != node.Operator && AreConstantExpressions(node.Left, node.Right)) { WarnAboutConstantExpression(node); } } }
public override List WalkMemberChain(MemberReferenceExpression memberRef) { List list = new List(); while (true) { MemberReferenceExpression target = memberRef.Target as MemberReferenceExpression; if ((target == null) || (this.IsSpecialMemberTarget(target) && this.IsReadOnlyMember(target))) { this.Warnings.Add(CompilerWarningFactory.AssignmentToTemporary(memberRef)); return(null); } if (this.IsSpecialMemberTarget(target) && !this.IsFieldReference(target)) { list.Insert(0, new ProcessAssignmentsToSpecialMembers.ChainItem(target)); } if ((target.Target is MethodInvocationExpression) || (target.Target is SlicingExpression)) { list.Insert(0, new ProcessAssignmentsToSpecialMembers.ChainItem(target.Target)); return(list); } if (this.IsTerminalReferenceNode(target.Target)) { return(list); } memberRef = target; } }
protected void WarnIfProtectedMemberInSealedClass(TypeMember member) { if (member.IsProtected && !member.IsSynthetic && !member.IsOverride && member.DeclaringType.IsFinal) { Warnings.Add(CompilerWarningFactory.NewProtectedMemberInSealedType(member)); } }
public override void Apply(Node targetNode) { if (!(targetNode is CompileUnit)) { Context.Warnings.Add(CompilerWarningFactory.CustomWarning(LexicalInfo, "Use [assembly: StrictMode]")); } Parameters.Strict = true; }
override public void LeaveLabelStatement(LabelStatement node) { if (null != node.Modifier) { Warnings.Add( CompilerWarningFactory.ModifiersInLabelsHaveNoEffect(node.Modifier)); } }
override public void LeaveBinaryExpression(BinaryExpression node) { if (BinaryOperatorType.Assign == node.Operator && (node.Right.NodeType != NodeType.TryCastExpression) && (IsTopLevelOfConditional(node))) { Warnings.Add(CompilerWarningFactory.EqualsInsteadOfAssign(node)); } }
void CheckUnusedLocals(Method node) { foreach (Local local in node.Locals) { InternalLocal entity = (InternalLocal)local.Entity; if (!entity.IsPrivateScope && !entity.IsUsed) { Warnings.Add(CompilerWarningFactory.UnusedLocalVariable(local, local.Name)); } } }
private void CheckEventUnsubscribe(BinaryExpression node, IEvent eventInfo) { var expected = ((ICallableType)eventInfo.Type).GetSignature(); var actual = GetCallableSignature(node.Right); if (expected != actual) { Warnings.Add( CompilerWarningFactory.InvalidEventUnsubscribe(node, eventInfo, expected)); } }
protected override void EmitIndexedPropertyDeprecationWarning(Property deprecated) { if (ActiveEnvironment.Instance == null) { return; } My <CompilerWarningCollection> .Instance.Add( CompilerWarningFactory.ObsoleteSyntax(deprecated, FormatPropertyWithDelimiters(deprecated, "(", ")"), FormatPropertyWithDelimiters(deprecated, "[", "]"))); }
protected override void EmitTransientKeywordDeprecationWarning(LexicalInfo location) { if (OutsideCompilationEnvironment()) { return; } EmitWarning( CompilerWarningFactory.ObsoleteSyntax( location, "transient keyword", "[Transient] attribute")); }
protected override void EmitIndexedPropertyDeprecationWarning(Property deprecated) { if (OutsideCompilationEnvironment()) { return; } EmitWarning( CompilerWarningFactory.ObsoleteSyntax( deprecated, FormatPropertyWithDelimiters(deprecated, "(", ")"), FormatPropertyWithDelimiters(deprecated, "[", "]"))); }
private void CheckNotFinalizer(Method node) { if (node.Name == "Finalize" && !node.IsSynthetic && node.IsOverride && 0 == node.Parameters.Count && 0 == node.GenericParameters.Count) { Warnings.Add( CompilerWarningFactory.OverridingFinalizeIsBadPractice(node)); } }
public INamespace Build() { try { CatalogPublicTypes(_assembly.GetTypes()); } catch (ReflectionTypeLoadException x) { My <CompilerWarningCollection> .Instance.Add(CompilerWarningFactory.CustomWarning("Could not load types from '" + _assembly + "': " + Builtins.join(x.LoaderExceptions, "\n"))); } return(_root); }
override public void LeaveBinaryExpression(BinaryExpression node) { CheckExpressionType(node.Right); if (BinaryOperatorType.ReferenceEquality == node.Operator) { if (IsTypeReference(node.Right)) { Warnings.Add( CompilerWarningFactory.IsInsteadOfIsa(node)); } } }
void MakeStaticIfNeeded(TypeMember node) { if (node.DeclaringType.IsStatic) { if (node.IsStatic) { Warnings.Add(CompilerWarningFactory.StaticClassMemberRedundantlyMarkedStatic(node, node.DeclaringType.Name, node.Name)); } node.Modifiers |= TypeMemberModifiers.Static; } }
private InvocationTypeInferenceRule ResolveRule(MethodInvocationExpression invocation, IMethod method, string rule) { var ruleImpl = typeof(BuiltinRules).GetMethod(rule); if (ruleImpl != null) { return((InvocationTypeInferenceRule)Delegate.CreateDelegate(typeof(InvocationTypeInferenceRule), ruleImpl)); } Warnings.Add(CompilerWarningFactory.CustomWarning(invocation, string.Format("Unknown type inference rule '{0}' on method '{1}'.", rule, method))); return(BuiltinRules.NoTypeInference); }
override public void LeaveExceptionHandler(ExceptionHandler node) { if (null != node.Declaration.Type.Entity && ((IType)node.Declaration.Type.Entity).FullName == "System.Exception" && !string.IsNullOrEmpty(node.Declaration.Name)) { if (null != NameResolutionService.ResolveTypeName(new SimpleTypeReference(node.Declaration.Name))) { Warnings.Add(CompilerWarningFactory.AmbiguousExceptionName(node)); } } }
void CheckAmbiguousVariableNames(Method node) { if (null == node.DeclaringType || null == node.DeclaringType.Entity) { return; } InternalClass klass = node.DeclaringType.Entity as InternalClass; if (null == klass || null == klass.BaseType) { return; } if (Parameters.DisabledWarnings.Contains("BCW0025")) { return; } klass = klass.BaseType as InternalClass; foreach (Local local in node.Locals) { if (null == local.Entity || ((InternalLocal)local.Entity).IsExplicit) { continue; } //check in the cache if variable is safe (the frequent case) if (_safeVars.Contains(local.Name)) { return; } //navigate down the base types bool safe = true; while (null != klass) { Field field = klass.TypeDefinition.Members[local.Name] as Field; if (null != field && field.IsPrivate) { safe = false; Warnings.Add(CompilerWarningFactory.AmbiguousVariableName(local, local.Name, klass.Name)); break; //no need to go further down } klass = klass.BaseType as InternalClass; } if (safe) //this var is safe for all methods of the current type { _safeVars.Add(local.Name); } } }
protected void WarnIfPrivateMemberNeverUsed(TypeMember node) { if (NodeType.Constructor == node.NodeType && node.IsStatic) { return; } if (!IsVisible(node) && node.ContainsAnnotation("PrivateMemberNeverUsed")) { Warnings.Add( CompilerWarningFactory.PrivateMemberNeverUsed(node)); } }
void CheckExplicitTypeForVisibleMember(TypeMember node) { if (node.IsSynthetic || !node.IsVisible) { return; } switch (node.NodeType) //TODO: introduce INodeWithType? { case NodeType.Constructor: CheckExplicitParametersType(node); return; case NodeType.Method: var method = (Method)node; if (method.IsPropertyAccessor()) { return; //ignore accessors } CheckExplicitParametersType(node); if (method.ReturnType != null) { return; } if (method.Entity != null && ((IMethod)method.Entity).ReturnType == TypeSystemServices.VoidType) { return; } break; case NodeType.Property: if (null != ((Property)node).Type) { return; } break; case NodeType.Event: if (null != ((Event)node).Type) { return; } break; default: return; //fields, nested types etc... } Warnings.Add(CompilerWarningFactory.VisibleMemberDoesNotDeclareTypeExplicitely(node)); }
public bool CanBeReachedFrom(Node anchor, IType expectedType, IType actualType) { bool byDowncast; if (!_typeSystemServices.Instance.CanBeReachedFrom(expectedType, actualType, out byDowncast)) { return(false); } if (byDowncast) { _warnings.Instance.Add(CompilerWarningFactory.ImplicitDowncast(anchor, expectedType, actualType)); } return(true); }
void AbstractMemberNotImplemented(ClassDefinition node, TypeReference baseTypeRef, IMember member) { if (IsValueType(node)) { Error(CompilerErrorFactory.ValueTypeCantHaveAbstractMember(baseTypeRef, node.FullName, GetAbstractMemberSignature(member))); } else if (!node.IsAbstract) { Warnings.Add( CompilerWarningFactory.AbstractMemberNotImplemented(baseTypeRef, node.FullName, GetAbstractMemberSignature(member))); _newAbstractClasses.AddUnique(node); } }
void CheckUnusedLocals(Method node) { foreach (Local local in node.Locals) { // _ is a commonly accepted dummy variable for unused items if (local.Name == "_") { continue; } InternalLocal entity = (InternalLocal)local.Entity; if (!entity.IsPrivateScope && !entity.IsUsed) { Warnings.Add(CompilerWarningFactory.UnusedLocalVariable(local, local.Name)); } } }
void CheckExplicitParametersType(TypeMember node) { INodeWithParameters @params = node as INodeWithParameters; if (null == @params) { return; } foreach (ParameterDeclaration p in @params.Parameters) { if (null == p.Type) { Warnings.Add(CompilerWarningFactory.VisibleMemberDoesNotDeclareTypeExplicitely(node, p.Name)); } } }
protected void CheckLikelyTypoInTypeMemberName(TypeMember member) { foreach (string name in GetLikelyTypoNames(member)) { if (name == member.Name) { return; } if (Math.Abs(name.Length - member.Name.Length) > 1) { continue; //>1 distance, skip } if (1 == StringUtilities.GetDistance(name, member.Name)) { Warnings.Add( CompilerWarningFactory.LikelyTypoInTypeMemberName(member, name)); break; } } }
private bool HandledAsDuplicatedNamespace(Import import, IEntity resolvedEntity) { var actualName = EffectiveNameForImportedNamespace(import); //only add unique namespaces var cachedImport = _namespaces[actualName] as Import; if (cachedImport == null) { _namespaces[actualName] = import; return(false); } //ignore for partial classes in separate files if (cachedImport.LexicalInfo.FileName == import.LexicalInfo.FileName) { Warnings.Add(CompilerWarningFactory.DuplicateNamespace(import, import.Namespace)); } BindError(import); return(true); }