I really like the new built in feature of VS11 to find 'Code Clones' but there does not seem to be any way to configure it.
An example would be only show me exact clones of 5 lines or more.
Right now it gives Exact, Strong, Medium and Weak matches and it seems like they are for 10 lines or more. If I could configure this it would help work through the clones and it would find me those small methods that I am sure have been cut and pasted over the years.
UPDATE
Here is the notes from the documentation for the Release Preview version about how to configure the ability to exclude generated files
To exclude files generated by T4 templates from code clone analysis
Place the templates in a sub directory of the Visual Studio project. Name it, for example, GeneratedFiles.
Add a new text file to the project, and change its name and extension to t4Exclusions.codeclonesettings
Change the content of the file as follows:
<CodeCloneSettings> <Exclusions> <File>GeneratedFiles*.cs</File> </Exclusions> </CodeCloneSettings>
UPDATE - 08/27/2012
I found this in the Code Clone documentation, it was not there in the earlier versions. It is one way to find clones of less than 10 lines long.
To find clones of a particular code fragment
1.
Highlight a fragment of code within a method or a get/set definition.
Note - You can find clones of statements, but not declarations such as field, method, or property signatures.
2.
On the shortcut menu for the fragment, choose Find matching clones in solution.
Use this method when you want to know if there is a similar method or fragment already in existence in your solution.
From the documentation:
Clones that are less than 10 statements long are not discovered by this command.
VS2015 handles clones in exact/strong/medium/weak for 2 lines or more.
Related
I read this post on the contents of a solution file, but still have no clue about the actual purpose of dependencies provided within a solution-file rather than within the project-file itself.
It seems there are two ways of having project 2 depending on project 1:
add a project-reference from p2 to p1. This will alter the csproj-file for p2 by introducing a ProjectReference to p1.csproj, but won´t change the solution, as far as I understand.
add an assembly-reference from p2 to p1. Thill will also alter the csproj-file by using a Reference to a compiled assembly (dll). However, it also adds a ProectDependency into the solution-file, which I do not understand. Why is this second entry within the solution needed in this case? Isn´t the assembly-reference provided within the csproj-file for p2 sufficient?
It's purely historical. The new project files don't really need it anymore, but the .sln file format predates msbuild and thus the solution file has some duplication.
It's used to define the build order, which becomes more important when you have ancient project types in your solution, as these won't be able to declare build order. It's also used to declare and validate build order between unrelated projects (e.g., project that don't reference each other), without the IDE having to load & parse all the projects.
Your second case is one of those cases where the solution file keeps track of build order. It then knows it needs to build P1 prior to P2. Without the solution level reference that information would be lost. It's quite clever that this is automatically detected and added, in the past you needed to manually define such build-order-dependencies.
At compile time the .sln is transformed into an msbuild file which then orchestrates the build. (see an example here). You can set an environment variable to generate yours.
<TL;DR>
The solution file is ancient and has some artefacts left over from pre msbuild. Some things just need to be there for 'reasons'.
If they were to build VS from scratch, the solution file would look very different.
Windows Version: Microsoft Windows [Version 10.0.14393]
MSBuild Version : Microsoft (R)-Buildmodul, Version 15.1.1012.6693
The project is written in C.
In the *.vcxproj files of this project there is a lot of code in like this
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
[do some stuff]
</ImportGroup>
for all configurations, 'Debug|Win32', 'Release|Win32', 'Debug|x64', 'Release|x64'. But I will have the same configuration for all combinations, therefore I do not want to write it 4 times making my project file 3 times longer and less readable .
Is there a shortcut like Condition="'$(Configuration)|$(Platform)'=='Any Configuration|Any Architecture'?
The standard way of doing this would be using 'property sheets'; more concrete: one property sheet with the common options which gets imported by all platform/configuration combinations. Some reasons to choose this approach:
it exactly addresses your "I will have the same configuration for all combinations, therefore I do not want to write it 4 times making my project file 3 times longer and less readable" requirement, and more: it keeps the common options in one single file, which can also be resued by other projects (which is really the number 1 selling point if you have multiple projects and want the same options for them)
it has user interface support for editing (though it's no problem if you'd want to manually edit the vcxproj to add it)
it keeps the standard project structure intact, so still allows for per-configuration and per-platform modifications should you need those
property sheets are just msbuild files like any other and as such can Import other files so you can create hierarchies with them, do things like having one master file which based on application type (exe/dll) sets different output paths and so on
You can remove the Condition attribute and have the ImportGroup being applied for every configuration.
Some colleagues, now departed, had the habit of adding new classes within a related class file.
This makes refactoring painful.
Is there a tool, perhaps within XCode or AppCode or just a simple script, that will split up these monster files?
It appears there is a tool to help with this in AppCode, but it only semi-automates the process.
I'm using AppCode 2.0, I don't know if the same tool is available in AppCode 1.x.
To extract one class from a file to a new file, right-click the#interface or #implementation line and select Refactor > Move. Alternatively press F6 on that line. You can now enter a new file name, though you probably want to copy+paste the class name in here. At this point you can also select any defines you want to move.
I have done some work on a script to extract all classes in a file. I'd love to share this one day, when I get the chance to remove our clients code from the unit tests!
I don't think so there is any tool for this. However you can write your own osx application for doing the same.
The application will ask to browse the file, and it will search for #interface....#endand#implementation....~#end` and will create a file from this. If a single file contains two classes then it will result in for files (two headers and two implementation). Then the original file can be deleted manually or automatically.
I think this above task can be completed in few hours.
Here you can go for save the original file in a folder, just in case you want to rollback.
I have a C# project which is built in a few different configurations. Some of the source files should be always included, and some only in certain configurations. So far I've been doing this with #if ... #endif around the entire files, but I was hoping to create a small extension to do this a nicer way.
I've created an extension that adds an item to files' context menus, but I can't find any way to set the Condition attribute on the item node in the project file.
I've looked at the Properties collection of the EnvDTE.ProjectItem interface, but can't see anything useful there (except BuildAction... I'll come back to that).
Then I tried getting an IVsBuildPropertyStorage on the item and calling SetItemAttribute(). This does add information to the project file, but as a child element like this:
<ItemGroup>
<Compile Include="Program.cs">
<Condition>%27%24%28Configuration%29%27==%27Debug%27</Condition>
</Compile>
</ItemGroup>
when what I was trying to achieve was:
<ItemGroup>
<Compile Include="Program.cs" Condition="'$(Configuration)'=='Debug'" />
</ItemGroup>
There's also an IVsBuildPropertyStorage.SetPropertyValue() but that adds a similar child element to a PropertyGroup section near the top, not to the item node.
I've looked at 'Project Subtypes/Flavors', but that looks like it's just going to get me another IVsBuildPropertyStorage, which doesn't seem to be useful. They do look capable of a lot of complex things, but documentation on the subject appears to be minimal and vague.
I've seen some posts describing how to use the MSBuild assemblies to directly load and manipulate the project file, but I'm not sure when is safe to do that without confusing Visual Studio and potentially losing changes, since VS prompts to reload when it detects changes to the project file.
As a last idea, I thought about manipulating the BuildAction property between Compile and None, but that sounds like it could be a lot of work for my extension to maintain correctly, keeping it in sync with every time the user switches configurations in the IDE for example.
Is there anyone with any experience with this kind of thing that has any advice to offer me, or should I give up hope and stick with manually adding #if directives everywhere?
You may like to explore the MSBuild option you mentioned.
You don't actually have to load the MSBuild project from file, because Visual Studio gives you a way of accessing the MSBuild project directly, i.e.:
string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
From there you can locate your specific items and potentially add the condition attribute, though I haven't tried this step myself (if this doesn't work, you might have to try modifying the project elements under the project.Xml property instead).
You can then call project.Save(), which shouldn't trigger the "Reload project?" dialog because of the way the MsBuild project instance is linked to the Visual Studio project hierarchy.
However, you may like to force Visual Studio to reload the project anyway, because if you switch build configurations (e.g. between Debug and Release), the MSBuild engine may not re-evaluate your item conditions during build. The code to do this programmatically can be found here:
How do I programmatically refresh/reload a VS project after modifying the underlying file?
Unfortunately I never got the time to persue the original goal of creating an extension for doing this, however I did achieve what I needed using the suggestion by lex-li: using separate project files per configuration.
Since the project files can all reside in the same directory, it's easy to simply use the 'Include/Exclude from project' context menu item in the solution explorer to choose which files are included. There's also no need for file linking this way, which I'd tried before and found very time-consuming to manage.
Partial Methods are also worth looking at, if you have similar needs. They allow you to define the signature of a method in one place, but optionally implement it elsewhere. If you don't implement it, no call is generated by the compiler.
With respect to the original idea of the extension, I suspect the answer by Daniel Nolan was heading in the right direction, but unfortunately I didn't get to try it out.
Xcode has a habit of putting all kinds of (redundant) information at the top of each code file it creates, containing copyright notices, class names, project names and client names. Like it or not, once you create a new class "A", then refactor it to be called "B", the information is wrong already. The comments will keep saying that this is "A.h" or "A.m". In addition, if you reuse classes from one project in a next, it will also state the wrong project name.
//
// A.h
// ProjectName
//
// Created by Author on 19-06-11.
// Copyright 2011 CompanyName. All rights reserved.
//
There must be a reason there aren't many people complaining about this. What is your trick to keep the header comments up to date? Is there a tool that auto-corrects it all? Is there a hidden setting?
Cheers,
EP.
There may be a way to update your comments but it will be tricky.
As far a customizing the template, this is not as bad. it is just a text file located in
/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/Cocoa Touch/
Don't edit the files here, they will get overwritten when you update, or reinstall xcode.
Place your custom templates here, in your home directory.
~/Library/Developer/Xcode/Templates/File Templates/
High Order Bit explains further.
Short Answer: Use SCM Commit Hooks (git example, svn example, cvs example)
Reason: Well, you can be rest assured that XCode will not do it. What XCode can do is attach itself to version control system. Its fairly simple to do using commit hooks that most SCMs support. They fire up before/after the commit/push so that source code is updated. You can even send automated emails when commiting etc.
Since GIT is the most popular one in my opinion these days, see this article.
I use custom templates (see #TMB's comment for a link explaining creating your own) that eliminate the project name and copyright info. File name changes rarely enough that that hasn't bothered me yet. If it became a problem, I would just eliminate it from my templates. If I did it again, I would eliminate the file line from the start: There are better and more reliable ways to figure out what file you're in than going to the top of the file.